| Autor |
Beitrag |
F34r0fTh3D4rk
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Do 26.05.05 14:31
Hallo, ich möchte ein bild laden, dieses intern auf die nächstgelegene Potenz von 2 strecken, dann in einem image mit stretch ausgeben, von dort aus aber irgendwie in der gestreckten größe weiterbenutzen, ok mein ansatz ist etwas umständlich deshalb möchte ich mein problem erklären:
-Ich habe ein image (später sinds mehrere), dort möchte ich ein bild reinladen, das gleiche bild soll dann als textur für ein opengl objekt genommen werden, welches ich dann vorher auf eine potenz von 2 strecken möchte (am besten strecken und nicht quetschen), wie mache ich das am besten ? ein bild in ne variable laden ? und wie mache ich das strecken und die berechnung ?
ich glaube ich lade ein bild und speicher den pfad, dann lade ich es nochmal extra ins opengl aber ich möchte es vorher auf eine potenz von 2 strecken also zb 2, 4, 8, 16, 32, ... 1024 ...
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 27.05.05 07:59
Wo liegt das Problem dabei: Beim Strecken oder bei der 2er-Potenz?
Das Strecken sollte mit BitBlt und internen Bitmap-Objekten relativ einfach sein.
Die 2er-Potenz: Weißt du nicht, wie du die nächste 2er-Potenz bekommst?
Einfach mit mod 2 die Differenz zum nächstunteren Wert holen, diese nächstuntere 2er-Potenz dann noch mit 2 multiplizieren.
|
|
Gausi
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Fr 27.05.05 08:13
_________________ We are, we were and will not be.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 27.05.05 08:16
NewSize := 1 shl ceil(ln( OldSize )/ln(2));Gibt auch noch Möglichkeiten ohne Floats aber dann kannste es (soweit ich es grad überblicken kann) nicht einfach auf eine Zeile schreiben.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 27.05.05 08:20
Autsch, klar, das ist Blödsinn.
Wie ich darauf gekommen bin, weiß ich schon nicht mehr, zuerst hatte ich auch mit ner Schleife überlegt, und dann gabs nen Kurzschluss im Gehirn  .

|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 27.05.05 08:50
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Fr 27.05.05 12:27
gut, danke, aber das mit dem strecken habe ich noch nicht hinbkommen
EDIT: habs hinbekommen:
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:
| function NextPotOfTwo(Number: integer): integer; var I, J: Integer; begin Result := 0; I := Number; J := I shr 1; J := J or J shr (1 shl 0); J := J or J shr (1 shl 1); J := J or J shr (1 shl 2); J := J or J shr (1 shl 3); J := J or J shr (1 shl 4); if J and I = 0 then J := I else J := (I and not J)*2; Result := J; end;
function ResizeBmp(bitmp: TBitmap; wid, hei: Integer): Boolean; var TmpBmp: TBitmap; ARect: TRect; begin Result := False; try TmpBmp := TBitmap.Create; try TmpBmp.Width := wid; TmpBmp.Height := hei; ARect := Rect(0, 0, wid, hei); TmpBmp.Canvas.StretchDraw(ARect, Bitmp); bitmp.Assign(TmpBmp); finally TmpBmp.Free; end; Result := True; except Result := False; end; end;
procedure TMainForm.Vorne1Click(Sender: TObject); begin if opendialog1.Execute then begin front.picture.loadfromfile(opendialog1.FileName); IMG_Front := Timage.Create(MainForm); try IMG_Front.Picture.loadfromfile(opendialog1.filename); ResizeBmp(IMG_Front.picture.Bitmap, NextPotOfTwo(IMG_Front.Width), NextPotOfTwo(IMG_Front.Height)); IMG_Front.picture.bitmap.PixelFormat := pf32bit; TFront.AssignFromBitmap(IMG_Front.picture.Bitmap); TFront.GenTexture; finally IMG_Front.Free; end; end; end; |

|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Fr 27.05.05 13:14
leider noch ein problem, wenn ein bild schon im richtigen format ist, dann wird es trotzdem größer gemacht und sieht dann als textur wieder pixelig aus, wie kann ich machen, dass ja nach dem was dichter ist (kleiner oder größer) es so gestreckt wird, dass die nächstgelegene 2er potenz erreicht ist, oder falls es schon eine ist, dass dann nichts passiert 
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 27.05.05 14:40
Liefert NextPotOfTwo nicht dieselbe Zahl zurück, wenn sie schon eine 2-er Potenz ist? Falls das nicht der Fall ist, ist's ein Programmierfehler von mir. Kann's im Moment nicht nachprüfen, da ich im Moment kein Zugang zu einem Delphi hab.
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Fr 27.05.05 14:42
nee es liefert die nächst höhere, die nächst niedrigere müsste da aber auch rein
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 27.05.05 15:18
Vielleicht probierst du das hier:
Delphi-Quelltext 1:
| NewSize := 1 shl round(ln( OldSize )/ln(2)); |
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Fr 27.05.05 15:20
jo der bringts, danke echt schon klein ^^
aber wenn es gleich ist scheint es immer noch nicht zu funktionieren, wie könnte ich denn abfragen, ob eine zahl eine potenz von 2 ist ?
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Fr 27.05.05 15:31
geht mit if zahl mod 2 = 0 then
oder so
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| function isMultipleOfTwo(zahl: dword): boolean; register; asm sar eax, 1 mov eax, 1 jc @false ret @false: mov eax, 0 end;
procedure TForm1.Button1Click(Sender: TObject); var zahl:integer; begin zahl := 3; if isMultipleOfTwo(zahl) then showmessage('true'); end; |
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Fr 27.05.05 15:34
| Zitat: |
if zahl mod 2 = 0 then
|
das gilt für gerade zahlen (multiplikanten von 2) (das wort hab ich mir grad ausgedacht  )
demnach wäre 10 eine potenz von 2 was ja nicht stimmt 
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Fr 27.05.05 15:43
ups, du meintest potenzen...wart mal kurz...ich überleg mir was 
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Fr 27.05.05 15:52
vielleich so ?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| function ispotoftwo(Number: integer): boolean; begin result := false; if (Number mod (1 shl round(ln(Number) / ln(2)))) = 0 then result := true; end;
function NearestPotOfTwo(Number: integer): integer; begin result := 1 shl round(ln(Number) / ln(2)); if ispotoftwo(number) then result := number; end; |
Zuletzt bearbeitet von F34r0fTh3D4rk am Fr 27.05.05 15:53, insgesamt 1-mal bearbeitet
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Fr 27.05.05 15:52
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| function isPotenzOfTwo(zahl: dword): boolean; register; asm xor ecx, ecx xor edi, edi @loop: cmp edi, 32 je @ende sar eax, 1 inc edi jnc @lastbitzero inc ecx @lastbitzero: jmp @loop @ende: cmp ecx, 1 je @true mov eax, 0 jmp @out @true: mov eax, 1 @out: end; |
edit: oder noch schneller: (falls jemand nen schnelleren weg kennt bitte schreien  )
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| function isPotenzOfTwo(zahl: dword): boolean; register; asm xor ecx, ecx cmp eax, 2 jl @false @loop: cmp ecx, 32 je @lookup sar eax, 1 inc ecx jc @lookup jmp @loop @lookup: cmp eax, 0 jg @false mov eax, 1 jmp @out @false: xor eax, eax @out: end; |
edit2: funktion 2 korriegiert ^^
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
Zuletzt bearbeitet von retnyg am Fr 27.05.05 16:26, insgesamt 2-mal bearbeitet
|
|
F34r0fTh3D4rk 
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Fr 27.05.05 15:55
scheint auch nicht zu gehen, wenn ich das bild nicht resize stimmt es
aber beide prozeduren scheinen zu stimmen
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:
| function ispotoftwo(Number: integer): boolean; asm xor ecx, ecx cmp eax, 2 jl @false @loop: cmp ecx, 32 je @lookup sar eax, 1 inc ecx jc @lookup jmp @loop @lookup: cmp eax, 0 jg @false mov eax, 1 jmp @out @false: xor eax, eax @out: end;
function NearestPotOfTwo(Number: integer): integer; begin if ispotoftwo(number) then result := number else result := 1 shl round(ln(Number) / ln(2)); end;
function ResizeBmp(bitmp: TBitmap; w, h: Integer): Boolean; var TmpBmp: TBitmap; ARect: TRect; begin Result := False; try TmpBmp := TBitmap.Create; try TmpBmp.Width := w; TmpBmp.Height := h; ARect := Rect(0, 0, w, h); TmpBmp.Canvas.StretchDraw(ARect, Bitmp); bitmp.Assign(TmpBmp); finally TmpBmp.Free; end; Result := True; except Result := False; end; end; |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure TMainForm.Rechts1Click(Sender: TObject); begin if opendialog1.Execute then begin SideR.picture.loadfromfile(opendialog1.FileName); IMG_Right := Timage.Create(MainForm); try IMG_Right.Picture.loadfromfile(opendialog1.filename); ResizeBmp(IMG_Right.picture.Bitmap, NearestPotOfTwo(IMG_Right.Width), NearestPotOfTwo(IMG_Right.Height)); IMG_Right.picture.bitmap.PixelFormat := pf32bit; TRight.AssignFromBitmap(IMG_Right.picture.Bitmap); TRight.GenTexture; finally IMG_Right.Free; end; end; end; |
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 27.05.05 17:16
F34r0fTh3D4rk hat folgendes geschrieben: | | nee es liefert die nächst höhere, die nächst niedrigere müsste da aber auch rein |
Bei mir funktioniert's:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| function NextPotOfTwo(I: integer): integer; var J: Integer; begin J := I shr 1; J := J or J shr (1 shl 0); J := J or J shr (1 shl 1); J := J or J shr (1 shl 2); J := J or J shr (1 shl 3); J := J or J shr (1 shl 4); if J and I = 0 then Result := I else Result := (I and not J)*2; end; | NextPotOfTwo(16)=16
NextPotOfTwo(32)=32
usw.
Wie ihr auch sieht ist bei mir die isPotenzOfTwo-Abfrage auch schon in der Funktion enthalten (siehe Highlight).
retnyg hat folgendes geschrieben: | falls jemand nen schnelleren weg kennt bitte schreien  |
Wie ich schon angegeben hab ist meine Funktion O(log(log(max(integer))) und deine O(log(Input)) (falls ich deinen Code richtig verstehe). Somit ist meine zu mindest asymptotisch gesehen viel schneller 
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Fr 27.05.05 17:23
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
|