Bonsoir, je vous expose le problème. Je tente en ce moment de charger un fichier XPM dans mon bitmap.
Jusque là pas de problèmes avec des images contenant un petit nombre de couleurs. Au delà d'un seuil (je pense au dessus de 32000 items mais pas vraiment certain ) et la paf.
Note : Le fichier que je tente de charger à 83071 couleurs
Pour le stockage de la palette de couleurs j'utilise un stringlist maison ou je génère un "hash" :
Lisez les commentaires dans le code
J'ai essayé avec un vieux code pour calculer avec un algo CRC32 mais idem, ainsi que d'autre formules mais ça foire si le nombre d'item à stocker est trop important.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 function ComputeSensitiveStringHash(const aString: string): integer; var i:integer; s:string; begin // trouvé sur le forum anglais de lazarus, si je me souviens // Fonctionne jusqu'à un nombre X de valeurs dans le tableau. Après il y a des "Duplicata" result:=0; for i:=1 to length(aString) do result:=result*$20844 xor ord(aString[i]); (* Cette méthode fonctionne très bien le seul soucis sa rapidité une vrai tortue s:=''; for i:=1 to length(aString) do begin s:=s+inttostr(ord(aString[i])); end; result:=strtoint(s); *) end;
Auriez vous une idée pour générer un code unique à chaque coup et performant en terme de rapidité ?
La difficulté c'est qu'a la fin je trie ma liste dans l'ordre croissant en utilisant le Hash comme paramètre
Pour mieux que vous compreniez pourquoi voici ma fonction de recherche :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 function CompareStringListItemHashText(item1, item2: TObject): Integer; begin result:=TGLZStringListItem(item1).getHashText-TGLZStringListItem(item2).getHashText; // le nom est mal choisi, mais le type est bien Integer end;
Ca fait des semaines que je suis dessus et je patoge dans la semoule aucune méthodes rapide ne fonctionne
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 function TCustomHashStringList.Find(Const S:String; var index: integer): boolean; var HashKey, Pivot, First, Last: Integer; found:Boolean; begin if Count = 0 then exit; if not(FIsSorted) then Sort; Index:=Count; Found := False; result:=false; First:=0; Last:=Count-1; // On génère le hash de S pour la comparaison if FCaseSensitive then HashKey:=ComputeSensitiveStringHash(S) else HashKey:=ComputeInSensitiveStringHash(S); // Quelques vérifications basiques // On vérifie avec le 1er item if HashKey = FDirectList^[0].getHashText then //if S=GetItem(0).Text then begin index := 0; Result := True; Exit; end; // On vérifie avec le dernier item if HashKey = FDirectList^[Last].getHashText then //if S=GetItem(Count-1).Text then begin index := Count-1; Result := true; Exit; end; // On borne par rapport à l'item du milieu de la liste // On choisi donc quelle partie chercher dans la liste // On réduit ainsi déja par 2 le nombre d'items à parcourir lors de la recherche Pivot :=(Count div 2); if HashKey = FDirectList^[Pivot].getHashText then //if S=GetItem(Pivot).Text then begin Index:=Pivot; Result:=true; Exit; end else if HashKey > FDirectList^[Pivot].getHashText then begin First:=Pivot; end else begin Last:=Pivot; end; Index:=Last; repeat // On borne par rapport au milieu de la tranche actuelle Pivot := ((First + Last) div 2); // On a trouvé on s'en va if HashKey =FDirectList^[Pivot].getHashText then begin Index:=Pivot; Result:=true; Exit; end else // On marque les nouvelles bornes de recherche if HashKey > FDirectList^[Pivot].getHashText then begin First:=Pivot; Dec(Index); end else begin Last:=Pivot-1; Index:=Last; // On laisse comme ca pour pouvoir sortir de la boucle Index < 0. On a n'a pas trouvé l'élément if Last<0 then Last:=0; // si négatif provoque une erreur end; // On vérifie si notre position est valide if (Index>=First) and (Index<=Last) then Found:=(FDirectList^[Index].getHashText=HashKey); until (Index<First) or (Index<0) or found; if found then result:=true; end;
Merci
Partager