PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Delphi: Wie JPEG laden? Und ...


aths
2004-09-21, 13:53:22
- Wie lädt man ein JPEG in ein TImage?

- Gibt es eine schnelle Methode, TIimage.Picture-Inhalte in ein Feld zu übertragen? (Mit Canvas.Pixels[X,y] jedes Pixel einzeln abzugreifen dauert ziemlicn lange.)

- Ähnlich den MP3-Tags scheints sowas auch für JPEG zu geben. Wie kann man auf solche JPEG-Dateiinformationen zugreifen? (Lesen und ändern/erstellen.)

Xmas
2004-09-21, 14:38:31
Soll eine Grafik auf einer Zeichenfläche ausgegeben werden, rufen Sie die Methode Draw oder StretchDraw des TCanvas-Objekts auf und übergeben die TPicture-Eigenschaft Graphic als Parameter.

http://www.funducode.com/freec/Fileformats/format3/format3b.htm

x-dragon
2004-09-21, 15:01:47
Wenn man die JPEG-Unit eingebunden hat, kann man die Bilder ganz normal über "Timage.Picture.LoadFromFile" laden.

Jazz
2004-09-23, 11:39:23
- Gibt es eine schnelle Methode, TIimage.Picture-Inhalte in ein Feld zu übertragen? (Mit Canvas.Pixels[X,y] jedes Pixel einzeln abzugreifen dauert ziemlicn lange.)
Jup, nimm einen Stream. Den kannst du dann mit SavetoStream befüllen.

aths
2004-09-23, 14:20:57
Jup, nimm einen Stream. Den kannst du dann mit SavetoStream befüllen.Könntest du konkreter werden, wie man aus einem TImage.Picture einen Stream macht?

Jazz
2004-09-23, 17:24:39
Natürlich:
var
ms : TMemoryStream;
begin
ms:=TMemoryStream.Create;
Image1.Picture.SaveToStream(ms);
...

Gruß,
Jazz

aths
2004-09-23, 21:53:02
Natürlich:
var
ms : TMemoryStream;
begin
ms:=TMemoryStream.Create;
Image1.Picture.SaveToStream(ms);
...

Gruß,
JazzProblem: SaveToStream gibts bei TPicture nur für CLX, nicht für VCL.

Nagelbrett
2004-09-24, 00:22:35
es gäbe noch die Möglichkeit, statt Canvas.Pixels einfach ScanLine zu benutzen, das sollte wesentlich schneller sein.
allerdings weiß ich gerade nicht, wie das da bei Bitmaps mit geringerer Farbtiefe ist...
ansonsten wohl so in etwa:

var
P: PByteArray;
y, x: Integer;
r, g, b: Byte;
begin
Image1.Picture.Bitmap.PixelFormat := pf24bit;
for y := 0 to Image1.Picture.Height-1 do
begin
P := Image1.Picture.Bitmap.ScanLine[y];
for x := 0 to Image1.Picture.Width-1 do
begin
r := P[x*3];
g := P[x*3+1];
b := P[x*3+2];
//wenn du den Farbwert als TColor möchtest, dann hier dann eben RGB(r,g,b) benutzen
//[...]
end;
end;
end;

kannst es natürlich auch erstmal nur zeilenweise speichern, wenn du nicht jedes Pixel einzeln benötigst...

Jazz
2004-09-24, 09:37:32
Problem: SaveToStream gibts bei TPicture nur für CLX, nicht für VCL.
Aber sowohl TBitmap als auch TJPEGImage haben unter VCL SaveToStream. Würde das reichen?

aths
2004-09-24, 15:58:39
es gäbe noch die Möglichkeit, statt Canvas.Pixels einfach ScanLine zu benutzen, das sollte wesentlich schneller sein.Ja, mit Scanlines habe ich schon gearbeitet. Das ist auch recht fix. Wäre aber nur zweite Wahl, da mit die Stream-Sache einfacher (und noch schneller) erscheint.

Aber sowohl TBitmap als auch TJPEGImage haben unter VCL SaveToStream. Würde das reichen?Kriegt man ein TPicture einfach in ein TBitmap?

Nagelbrett
2004-09-24, 17:38:07
Kriegt man ein TPicture einfach in ein TBitmap?
DeineBitmap.Assign(DeinPicture.Graphic);
evtl kannst du aber auch direkt mit DeinPicture.Bitmap darauf zugreifen (funktioniert jedoch z.b. nicht, wenn du einem TImage während der Design-Zeit über den Objektinspektor ein Picture zugewiesen hast... nach LoadFromFile o.ä. geht's aber)

aths
2004-09-24, 18:27:50
Hm, das ist hässlich: Bei TBitmap funktioniert LoadFromFile natürlich nur mit einem BMP. Um JPEGs zu benutzen müsste man erst in ein TPicuture laden und als BMP abspeichern. Leider speichert er das TPicuture dann aber wieder als JPEG. Die Hilfe sagt zudem: Bitmap referenziert das Grafikobjekt, sofern es ein Bitmap enthält. Wenn Sie mit Bitmap auf ein TPicture-Objekt verweisen, das eine Metadatei oder ein Symbol enthält, wird keine Grafikkonvertierung durchgeführt, sondern der Inhalt des Objekts verworfen und ein neues, leeres Bitmap zurückgegeben.

Lädt man ein BMP, enthält der Memorystream von TBitmap auch den Header. Das ist natürlich ein bisschen blöd. Ich brauche nicht das binäre BMP, sondern den Bildinhalt als RGB.

Zur Not müsste ich das Bild doch Pixelweise auslesen und es mit Scanline neu rendern. Lieber wäre mir natürlich, nach dem JPEG-Laden direkt auf das TPicture zugreifen zu können.