![]() |
Bild formatunabhängig 90° drehen
Hi,
gibt es eine Möglichkeit, ein TPicture oder noch besser TCanvas um 90° zu drehen und das ganze ohne TBitmap ? Habe bisher nur bitmapbasierende Methoden gefunden, aber Bitmaps kommen bei mir nicht in Frage. |
Re: Bild formatunabhängig 90° drehen
Ist Umständlich, aber
mit Canvas.Pixels bekomst du jeden Wert. Den kannst du in ein Array speichern ( Im Prionzip ist ein TBitmap, ja nichts anderes ) Dann Drehst dud as Array und kannst mit Canvas.pixels wieder zurückschreiben. Das ganze hat nur den Hacken das Canvas.pixels eben unheimlich langsam arbeitet, weswegen alle Welt das mit TBitmap macht, denn da hat man Scanline |
Re: Bild formatunabhängig 90° drehen
Hm, ist bloß die Frage, ob es schneller ginge, erst ein beliebiges Format zu konvertieren um dann für einen kurzen Moment Scanline zu nehmen.
|
Re: Bild formatunabhängig 90° drehen
Also wenn wir davon ausgehen das dein Bild 1 M Pixel ist dann auf alle Fälle Ja.
Canvas.Pixels ist wirklich Extrem Langsam. Im Zweifel probiere es aus. |
Re: Bild formatunabhängig 90° drehen
Mit PlgBlt kannst du ein Bild auf einer Canvas drehen.
|
Re: Bild formatunabhängig 90° drehen
Mal anders gefragt. Wieso kommen bei dir Bitmaps nicht in Frage? Denn die Methode zum Zeichnen auf einer Canvas benötigen im Hintergrund eigentlich irgendwo immer ein Bitmap. Bei geladenen JPEGs schmettert es aber bereits die Klasse ab. Also dort kann man das Canvas nur zum Lesen benutzen. Zum Zeichnen braucht man wieder ein Bitmap.
|
Re: Bild formatunabhängig 90° drehen
Die Lösung ist simpel, man muss aber erstmal drauf kommen. Man zeichnet sich die JPG/PNG/... auf ein TBitmap. Dann kann man mit Hilfe dieses Bitmaps machen was man will, sogar zum Schluss ein TPicture/TGraphic zurückgeben. Diese Funktion lag schon seit langem in fehlerhafter Form auf meiner Platte, sie ist also nur in geringer Form von mir, da sie vorher schon funktionierte. Sie hatte allerdings ein paar Fehler bzw. es fehlten für meine Verwendungszwecke noch Sachen. Die Sache mit dem TPicture als Rückgabewert und dass es überhaupt eine Funktion ist (war vorher eine Prozedur) stammen zum Beispiel von mir. Die Funktion ist auf jeden Fall schnell genug und konvertieren muss man in dem Sinne schon, allerdings unabhängig vom Dateiformat, solange dieses von Delphi unterstützt wird. Der Vorschlag es zu konvertieren kam von eurer Seite schon, allerdings verstand ich ihn etwas falsch, weil ich sofort ein die Funktion JPGtoBMP dachte, die irgendwo in meinen Units noch vor sich hin gammelt. Dann auf jeden Fall ein großes Danke, denn eure Vorschläge waren allesamt gut und ich hätte es auch schnell alles umsetzen können, hätte ich euch sofort verstanden.
Delphi-Quellcode:
type
TRGBQuad = packed record B, G, R, A : Byte; end; PRGBQuad =^TRGBQuad; TRGBarray = Array[0..0] of TRGBQuad; function Rotate90(const Source : TGraphic) : TPicture; var P : PRGBQuad; Y, X, H, W : Integer; RowOut : ^TRGBarray; SrcBmp : TBitmap; begin SrcBmp := TBitmap.Create; with SrcBmp do begin PixelFormat := pf32bit; Height := Source.Height; Width := Source.Width; Canvas.Draw(0, 0, Source); end; if Result <> nil then Result := TPicture.Create; Result.Bitmap.PixelFormat := pf32bit; W := SrcBmp.Height; H := SrcBmp.Width; Result.Bitmap.Height := H; Result.Bitmap.Width := W; for Y := 0 to Pred(H) do begin RowOut := Result.Bitmap.ScanLine[Y]; P := SrcBmp.ScanLine[Pred(SrcBmp.Height)]; inc(P, Y); for X := 0 to Pred(W) do begin RowOut[X] := P^; inc(P, H); end; end; SrcBmp.Free; end; |
Re: Bild formatunabhängig 90° drehen
und mit der Nutzung von Scanline ist es wirklich schneller als mit PlgBlt? Kann ich fast nicht glauben.
|
Re: Bild formatunabhängig 90° drehen
Ich schreibe hier, weil der Thread noch relativ kurz und übersichtlich scheint:
Alle Drehalgorhytmen haben - wenn ich das richtig sehe - gemeinsam, dass sie die Pixel über Scanlines ansprechen, die wiederum aus mehrdimensionale Arrays zusammengesetz sind. Egal welchen Code ich mir hier ansehe, werden die Bilder vor dem Drehen unabhängig von ihrer bisherigen Bittiefe auf 24 oder gar 32 bit gesetzt. Das an sich ist ja auch OK und mir letztlich egal. Wie bringe ich es fertig, das Bild hinterher wieder Schwarzweiß (pf1bit) zu machen? Durch das Setzen des Pixelformats klappt es jedenfalls bei mir nicht. Das Bild bekommt dann immer einen Blaustich. |
Re: Bild formatunabhängig 90° drehen
Hallo,
ich weiß, dass das Thema schon alt ist. Ich will aber kein neues aufmachen, weil die Frage im Thema den Nagel auf den Kopf trifft.Ich drehe meine Bilder jetzt mit ![]() Wie drehe ich das Bild gegen den Uhrzeigersinn? Gruß, Alex |
Re: Bild formatunabhängig 90° drehen
Die Punkte geben die gewünschte Position an:
Der erste Punkt: Die obere, linke Ecke wird zum ersten Punkt verschoben, die obere rechte Ecke wird zum 2. Punkt verschoben und die untere linke Ecke wird zum dritten Punkt verschoben ;) Um 90° gegen den Uhrzeigersinn zu rotieren musst du: Die OL-ecke nach unten verschieben die OR-Ecke nach links und die UL-Ecke nach rechts verschieben ;) |
Re: Bild formatunabhängig 90° drehen
Zitat:
Zitat:
Delphi-Quellcode:
Gruß und Dank, Alex
Points[0]:=Point(0,tmpBitmap.Width);
Points[1]:=Point(0,0); Points[2]:=Point(tmpBitmap.Height,tmpBitmap.Width); Nachfrage: Gibt es eine noch schnellere, ähnlich einfache Methode? Für das Drehen eines Bildes mit 1660x2340 braucht mein Celereon M mit 1,86 GHz immerhin ca. 470 ms. |
Re: Bild formatunabhängig 90° drehen
Du könntest hier mal die vierte probiren, vielleicht ist das etwas schneller:
![]() Also das Bitmap kopieren (evtl. mit BitBlt statt Bitmap.Assign) dann auf advanced setzen, dann setworldtransform aufrufen und dann mit bitblt wieder rüberkopieren. |
Re: Bild formatunabhängig 90° drehen
Zitat:
Jetzt eine weitere Frage: Warum wird das Bild mit diesem Code nicht um 180' gedreht?
Delphi-Quellcode:
Ich bin wieder nach demselben Muster wie beim Drehen nach links bzw. rechts vorgegangen. Die erste Ecke nach ... usw. Und trotzdem klappt es nicht. Ich habe es mehrmals mit Zetteln probiert, wo ich in die Ecken die Zahlen gemahlt hatte.
Points[0]:=Point(help.Height,help.Width);
Points[1]:=Point(help.Height,0); Points[2]:=Point(0,help.Width); Geht des nicht mit PlgBlt? Gruß und schonmal schönes WE, Alex |
Re: Bild formatunabhängig 90° drehen
Ich tippe darauf:
Delphi-Quellcode:
Guck mal ob das geht ;)
Points[0]:=Point(help.Height,help.Width);
// Obere, linke Ecke soll nach unten rechts - okay ... aber nur für quadratische Bilder. // Mein Tipp: Points[0]:=Point(help.Width,help.Height); Points[1]:=Point(help.Height,0); // Obere, rechte Ecke soll nach ... oben rechts?? // Mein Tipp: Points[1]:=Point(0,help.Height); Points[2]:=Point(0,help.Width); // Untere, linke Ecke soll nach ... unten links? // Mein Tipp: Points[2]:=Point(help.Width,0); |
Re: Bild formatunabhängig 90° drehen
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Generellt dreht er das Bild so tatsächlich um 180'. Aber es gibt dann einen Rand um das Bild, der nicht gedreht wird (obere Zeile und linke Spalte). Da immer die Minimalwerte genommen werden (0 und 0), kann ich mir das nicht erklären. Außerdem stimmt das mit dem Quadrat auch nur fast. Denn wenn ich das Bild um 180' drehe, hat es meiner Meinung nach dieselben Abmessungen wie das Ausgangsbild. Aus 320x234 werden doch wieder 320x234; nur eben auf dem Kopf. Aus diesem Grunde steht ja sicherheitshalber auch noch
Delphi-Quellcode:
mit dabei, bevor PlgBlt ausgeführt wird...
Image1.Picture.Bitmap.Width:=help.Width;
Image1.Picture.Bitmap.Height:=help.Height; Woher kommt jetzt wieder der Rand? Soll ich nochmal meinen aktuellen Code hochladen? Gruß, Alex |
Re: Bild formatunabhängig 90° drehen
Für die Drehung um 180° habe ich leider noch keine Lösunmg gefunden, die 100%ig funktioniert. Aber ich habe ein weiteres Problem:
Mein Programm war nur die Übrung für etwas größeres :lol:. Ich scanne mehrere Bilder mit einem Scanner ein und möchte die dann drehen und strecken bzw. stauchen. Ich habe nun den Code an mein bestehendes Programm angepasst und nun funktioniert er nicht mehr. Ich scanne die Bilder ein und packe Sie alle in eine TObjectList, wobei ich die Liste mit Bilder.Add(TBitmap.Create); erweitere und die Bilder mit TBitmap(Bilder.Last).Assign(Image); ablege. Wenn der Scanner fertig ist, werden die der Reihe nach wieder ausgelesen und aus der Liste gelöscht. Theoretisch müsste das hier doch klappen:
Delphi-Quellcode:
Aber leider bekomme ich nur ein Bild, bei dem sich Höhe und Breite geändert haben. Das ist logisch, weil diese geändert werden. Ich habe die Vermutung, dass PlgBlt nicht (richtig) ausgeführt wird. Bei meinen Versuchen, dieses mittels einer Bool-Variable abzufragen, bekomme ich immer ein positives Ergebnis (=dasselbe wie in meinem Testprogramm, wo es ja klappt).
TBitmap(Bilder.Items[0]).Width:=help.Height;
TBitmap(Bilder.Items[0]).Height:=help.Width; Points[0]:=Point(0,help.Width); Points[1]:=Point(0,0); Points[2]:=Point(help.Height,help.Width); PlgBlt(TBitmap(Bilder.Items[0]).Canvas.Handle, Points, help.Canvas.Handle, 0, 0, help.Width, help.Height, 0, 0, 0); Was mache ich falsch? :wall: |
Re: Bild formatunabhängig 90° drehen
Zitat:
Ich habe mehrere Bilder erzeugt/erzeugen lassen. Ab einer bestimmten Größe klappt PlgBlt nicht mehr. In meinem Fall sind das Bilder mit den Maßen 8,3 x 11,7 Zoll (= DIN A4). Bis exakt 293 dpi (= 2432 x 3428) klappt es prima. Ab den nächstgrößeren Pixeln geht nichts mehr. Es wird nur noch der erste Schritt getan; nämlich die Abmessungen des Bildes vertauscht. Ich weiß auch nicht, ob das eventuell ein Phänomen von TurboDelphi 2006 sein kann. Ich schließe das fast aus, weil es sich - korrigiert mich, wenn's falsch ist - bei PlgBlt um eine Windows-Funktion handelt. Kann mir da bitte jemand weiter helfen? Gibt es noch andere Funktionen? Alex |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz