AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi bitmap um ein vielfaches von 90 drehen

bitmap um ein vielfaches von 90 drehen

Ein Thema von nebukadnezzar · begonnen am 15. Jan 2003 · letzter Beitrag vom 20. Jan 2003
Antwort Antwort
nebukadnezzar

Registriert seit: 18. Dez 2002
38 Beiträge
 
Delphi 6 Personal
 
#1

bitmap um ein vielfaches von 90 drehen

  Alt 15. Jan 2003, 11:57
ich möchte ein bitmap halt um 0,90,180,270 Grad drehen
das gedrehte image soll dirket auf ein canvas gemalt werden.
das ganze sollte auch noch möglichst schnell gehen und mit
den verschiedenen Pixelformaten klar kommen.

nur wie geht das?

(das fon efg's Labs versteh ich nicht)
  Mit Zitat antworten Zitat
Benutzerbild von illegal eagle
illegal eagle

Registriert seit: 15. Jan 2003
Ort: Jena
10 Beiträge
 
Delphi 5 Standard
 
#2
  Alt 15. Jan 2003, 20:52
Hi!

Für 180° (oben nach unten umdrehen) sollte folgender Code gehen: (nicht getestet)

Delphi-Quellcode:
Procedure Turn180(Bitmap : tBitmap);
Type tLine : Array[0..$FFFF] of Byte;
Var LineWidth, y : Integer;
        Line : ^tLine;
Begin
LineWidth := Bitmap.Width;
Case Bitmap.PixelFormat of
        pf1Bit : LineWidth := LineWidth SHR 3;
        pf4Bit : LineWidth := LineWidth SHR 1;
        pf16Bit : LineWidth := LineWidth SHL 1;
        pf24Bit : LineWidth := LineWidth * 3;
        pf32Bit : LineWidth := LineWidth SHL 2;
End;
GetMem(Line, LineWidth);
For y := 0 to ((Bitmap.Height - 1) div 2) do Begin
        Move(Bitmap.ScanLine[Bitmap.Height - 1 - y]^, Line[0], LineWidth;
        Move(Bitmap.ScanLine[y]^, Bitmap.ScanLine[Bitmap.Height - 1 - y]^, LineWidth;
        Move(Line[0], Bitmap.ScanLine[y]^, LineWidth;
End;
FreeMem(Line, LineWidth);
End;
Für 90° und 270° mußt du ein neues (temporäres) Bitmap erstellen, weil sich ja wahrscheinlich die Abmessungen ändern werden.
  Mit Zitat antworten Zitat
Sebastian Nintemann
(Gast)

n/a Beiträge
 
#3
  Alt 15. Jan 2003, 22:10
Für 180° kannst du dir auch mal StretchBlt angucken, damit gehts in einer Zeile. Für 90°/270° mal Mit Scanline rumexperimentieren, ist garnicht so einfach, aber zu schaffen. Mit den unterschiedlichen Pixelformaten ists mit Scanline natürlich auch nicht so ganz einfach, kannst du nicht vor dem bearbeiten auf pf24bit einstellen?
Gruß, Sebastian
  Mit Zitat antworten Zitat
Benutzerbild von illegal eagle
illegal eagle

Registriert seit: 15. Jan 2003
Ort: Jena
10 Beiträge
 
Delphi 5 Standard
 
#4
  Alt 16. Jan 2003, 10:29
Sorry, der Code spiegelt das Bild nur, es muss noch von links nach rechts umgedreht werden.
Ich hoffe, du bekommst keine Abstürze wegen Scanline! Ist (wie gesagt) nicht getestet.
  Mit Zitat antworten Zitat
nebukadnezzar

Registriert seit: 18. Dez 2002
38 Beiträge
 
Delphi 6 Personal
 
#5
  Alt 16. Jan 2003, 16:29
aus dem obigen vorgeschlagenen Code hab ich folgendes gemacht:
Delphi-Quellcode:
Procedure Turn(bitmap,dest:tBitmap;a:integer);
Type tLine = Array[0..0] of Byte;
        pline = ^tLine;
Var Linesize,Linesize2, y, x : Integer;
        Field,temp : pline;
        Pixsize : Longint;
        FieldSize : Longint;
Begin
if Bitmap.Pixelformat in [pf1Bit,pf4Bit] then Bitmap.PixelFormat:=pf16bit;
Dest.PixelFormat:=Bitmap.PixelFormat;
Case Bitmap.PixelFormat of
        pf16Bit : Pixsize:=2;
        pf24Bit : Pixsize:=3;
        pf32Bit : Pixsize:=8;
End;
Linesize:=Bitmap.width * Pixsize;
FieldSize:=Linesize*Bitmap.Height;

GetMem(Field, fieldSize);
For y:=0 to Bitmap.height-1 do
        Move(Bitmap.ScanLine[y]^, Field[y*Linesize], LineSize);

Case a of
          0:BEgin
                 Dest.Width:=Bitmap.Width;
                 Dest.Height:=Bitmap.Height;
                 Linesize2:=Pixsize*Dest.width;
            End;
         90:BEgin
                 Dest.Width:=Bitmap.Height;
                 Dest.Height:=Bitmap.Width;
                 Linesize2:=Pixsize*Dest.width;
                 Getmem(temp,Fieldsize);
                 For y:=0 to Bitmap.Height-1 do
                  For x:=0 to Bitmap.width-1 do
                   Begin
                        Move(Field[(y)*Linesize + (x)*Pixsize],temp[(x)*Linesize2 + (bitmap.height -y -1)*Pixsize],Pixsize);
                   End;
                 Freemem(field,Fieldsize);
                 Field:=temp;
            End;
         180:Begin
                 Dest.Width:=Bitmap.Width;
                 Dest.Height:=Bitmap.Height;
                 Linesize2:=Pixsize*Dest.width;
                 Getmem(temp,Fieldsize);
                 For y:=0 to Bitmap.Height-1 do
                  For x:=0 to Bitmap.width-1 do
                   Begin
                        Move(Field[(Bitmap.height -y -1)*Linesize + (Bitmap.width - x -1)*Pixsize],temp[y*Linesize2 + x*Pixsize],Pixsize);
                   End;
                 Freemem(field,Fieldsize);
                 Field:=temp;
             End;
        270:BEgin
                 Dest.Width:=Bitmap.Height;
                 Dest.Height:=Bitmap.Width;
                 Linesize2:=Pixsize*Dest.width;
                 Getmem(temp,Fieldsize);
                 For y:=0 to Bitmap.Height-1 do
                  For x:=0 to Bitmap.width-1 do
                   Begin
                        Move(Field[(y)*Linesize + (x)*Pixsize],temp[(Bitmap.width - x -1)*Linesize2 + (y)*Pixsize],Pixsize);
                   End;
                 Freemem(field,Fieldsize);
                 Field:=temp;
            End;
End;

For y:=0 to Dest.height-1 do
        Move(Field[y*Linesize2],Dest.ScanLine[y]^,Linesize2);
Freemem(Field,Fieldsize);
End;
für verbesserungen hab ich immer ein offenes ohr
für 1 und 4 bittige bilder funzt das nicht deswegen wird dann auf 16bit gezwungwn (weil dann 0 < pixsize <1 )
  Mit Zitat antworten Zitat
Benutzerbild von illegal eagle
illegal eagle

Registriert seit: 15. Jan 2003
Ort: Jena
10 Beiträge
 
Delphi 5 Standard
 
#6
  Alt 16. Jan 2003, 18:12
Bei 32 Bits würde ich Pixsize nicht auf 8, sondern auf 4 setzen.

Und warum nimmst du Array[0..0] of Byte? Damit erhältst du doch einen Fehler, wenn du die Bereichsprüfung eingeschaltet lässt (mach ich immer so).

Move(Field[(y)*Linesize + (x)*Pixsize],temp[(x)*Linesize2 + (bitmap.height -y -1)*Pixsize],Pixsize);

scheint mir etwas komisch,

Move(Field[((y * Linesize) + x) * Pixsize], temp[((x * Linesize2) + bitmap.height - y - 1) * Pixsize], Pixsize);

sieht besser aus.
  Mit Zitat antworten Zitat
nebukadnezzar

Registriert seit: 18. Dez 2002
38 Beiträge
 
Delphi 6 Personal
 
#7
  Alt 16. Jan 2003, 19:15
Linesize is ja schon die anzahl der bytes und nicht die anzahl der pixel
(linesze:= width * pixelsize)


das problem is nur das de Prozedur einfach VIIIIEEEEEELLLLL zu lange dauert
  Mit Zitat antworten Zitat
Benutzerbild von illegal eagle
illegal eagle

Registriert seit: 15. Jan 2003
Ort: Jena
10 Beiträge
 
Delphi 5 Standard
 
#8
  Alt 20. Jan 2003, 15:08
Wenn's dir zu langsam ist, dann nimm doch den Code vom efg Lab.
Besonders Unit7 sollte man mal ausprobieren.
  Mit Zitat antworten Zitat
nebukadnezzar

Registriert seit: 18. Dez 2002
38 Beiträge
 
Delphi 6 Personal
 
#9
  Alt 20. Jan 2003, 16:41
hab ich schon längst und unit7 habe ich für meine zwecke vorerst als optimal lösung aus erkoren
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf