![]() |
Delphi-Version: 5
Pixel aus Datei wieder geben
Hallo
Ich möchte gerne ein Bild mit canvas.pixels durchlaufen. Diese dann als Integers in einer Datei Speichern. Dann auf einem neuen Knopf die Datei öffnen und die gespeicherten Pixel Integerwerte in einem neuen Anlauf wieder darstellen. Hier mal mein Versuch Im zweiten Bild kommt nur ein schwarzer Strich ganz oben in der ersten Reiche und von oben nach unten ganz links. Ich habe keine Ahnung was ich falsch mache??
Delphi-Quellcode:
unit Unit1;
{$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls; type { TForm1 } TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Edit1: TEdit; Image1: TImage; Image2: TImage; Image3: TImage; Label1: TLabel; Label2: TLabel; Memo1: TMemo; OpenDialog1: TOpenDialog; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { private declarations } public { public declarations } end; var Form1: TForm1; F:File of integer; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject); var filename:string; filesize,len:Int64; begin if opendialog1.execute then begin filename:=opendialog1.filename; end; image1.picture.loadfromfile(filename); end; procedure TForm1.Button2Click(Sender: TObject); var bildhoehe,bildbreite,zeile,spalte,farbe,X,Y: integer; b:byte; begin application.processmessages; ASSIGNFILE(f,'NeuesBild.dat'); REWRITE(F); for spalte:=0 to image1.width-1 do begin application.processmessages; for zeile:=0 to image1.height-1 do begin application.processmessages; farbe:=image1.Canvas.Pixels[spalte,zeile]; //Image2.Canvas.pixels[spalte,zeile]:=farbe; //b:=farbe; //label1.caption:=inttostr(b); write(f,farbe); end; end; //image1.canvas.brush.color:=255; //image2.canvas.fillrect(rect(50,50,150,150)); Closefile(f); end; procedure TForm1.Button3Click(Sender: TObject); var farbwert:byte; begin farbwert:=strtoint(Edit1.text);//image1.canvas.pixels[40,40]; label2.caption:=inttostr(farbwert); image3.canvas.brush.color:=farbwert; image3.canvas.fillrect(rect(0,0,image3.height,image3.width)); end; procedure TForm1.Button4Click(Sender: TObject); var index1,index2,farbe1: integer; begin ASSIGNFILE(f,'NeuesBild.dat'); RESET(f); READ(F,farbe1); For index1:=1 to 300 do begin for index2:=1 to 300 do begin image2.canvas.pixels[index1,index2]:=farbe1; end; end; Closefile(f); end; end. |
AW: Pixel aus Datei wieder geben
Hallo,
im Button4.click liest Du einmal die farbe1 ein und gibts diese 300 x 300 mal aus. Grüße Klaus |
AW: Pixel aus Datei wieder geben
mhh aber müsste ich nicht in der datei 300 x 300 den jeweiligen Farbwert als Integer in meiner Datei stehen haben?
|
AW: Pixel aus Datei wieder geben
Korrekt wäre :
For index1:=1 to 300 do begin for index2:=1 to 300 do begin READ(F,farbe1); image2.canvas.pixels[index1,index2]:=farbe1; end; end; Allerdings frage ich mich, wieso Du nicht blockwrite/blockread benutzt. Und ist das wirklich Delphi ? Dann hieße es doch nicht {$R *.lfm} sondern {$R *.dfm} |
AW: Pixel aus Datei wieder geben
Super Danke das hat funktioniert
|
AW: Pixel aus Datei wieder geben
Zitat:
|
AW: Pixel aus Datei wieder geben
Zwischendurch habe ich das mal praktisch ausprobiert. Beim Einlesen muß es natürlich auch von 0 bis 299 statt von 1 bis 300 heißen, denn sonswt kommt es tatsächlich zu den abgesetzten Linien oben und links.
Ich habe mal die Umsetzung mit BlockWrite/BlockRead vorgenommen. Hier nur die entsprechenden Änderungen, allerdings nicht optimiert, sondern noch aus der Testphase :
Delphi-Quellcode:
BlockWrite/BlockRead haben den Vorteil, daß die Daten im Stück geschrieben bzw. gelesen werden. Das geht schneller als pixelweise vorzugehen. Wenn erst noch Breite und Höhe mitgespeichert werden, ist das alles etwas flexibler. Allerdings ist mir noch nicht geglückt, das mit offenen Arrays umzusetzen, so daß leider die Bildgröße doch noch vorher feststehen muß. Sicher wäre auch möglich, mit "ScanLine" statt mit Pixeln zu arbeiten, aber das kommt immer auf den Anwendungszweck an.
f : file; // F:File of integer;
procedure TForm1.Button1Click(Sender: TObject); var filename:string; filesize,len:Int64; begin if opendialog1.execute then begin filename:=opendialog1.filename; end; image1.picture.loadfromfile(filename); image1.width:=image1.picture.width; // flexible Anpassung der Breite image1.height:=image1.picture.height; // flexible Anpassung der Höhe end; procedure TForm1.Button2Click(Sender: TObject); var bildhoehe,bildbreite,zeile,spalte,farbe,X,Y: integer; TestArray: array [0..299, 0..299] of integer; index1,index2,farbe1: integer; b:byte; begin application.processmessages; bildbreite:=image1.width; bildhoehe:=image1.height; For index1:=0 to {299} bildbreite-1 do begin for index2:=0 to {299} bildhoehe-1 do begin TestArray[index1,index2]:=image1.canvas.pixels[index1,index2]; end; end; ASSIGNFILE(f,'NeuesBild.dat'); REWRITE(F,1); blockwrite(f,image1.width,sizeof(bildbreite)); blockwrite(f,image1.height,sizeof(bildhoehe)); blockwrite(f,TestArray,bildhoehe*bildbreite*sizeof(integer)); Closefile(f); end; procedure TForm1.Button4Click(Sender: TObject); var bildhoehe,bildbreite, menge, index1,index2,farbe1: integer; TestArray: array [0..299, 0..299] of integer; // TestArray: array of array of integer; begin ASSIGNFILE(f,'NeuesBild.dat'); RESET(f,1); //READ(F,farbe1); blockread(f,bildbreite,sizeof(bildbreite)); blockread(f,bildhoehe,sizeof(bildhoehe)); menge:=bildbreite*bildhoehe*sizeof(integer); //setlength(TestArray,menge); //showmessage(inttostr(menge)); blockread(f,TestArray,menge); Closefile(f); image2.width:=bildbreite; image2.height:=bildhoehe; For index1:=0 to {299} bildbreite-1 do begin for index2:=0 to {299} bildhoehe-1 do begin image2.canvas.pixels[index1,index2]:=TestArray[index1,index2]; end; end; // Image2.Refresh; { must refresh before changes are displayed } end; |
AW: Pixel aus Datei wieder geben
Statt mit typisierten Dateien ("file of ...") zu doktorn, wäre es meiner Meinung nach weiser gleich mit Streams umzugehen zu lernen. Insbesondere weil Streams auch ausserhalb von Dateiverarbeitung an jeder Ecke vorkommen, und ganz besonders dann, wenn man mal über den Delphi-Tellerrand hinweg lugt.
|
AW: Pixel aus Datei wieder geben
@Medium ich sehe es im Prinzip genau so, wenn man aber sieht wo es überall hakt, ist es vielleicht besser das Fass jetzt nicht aufzumachen.
|
AW: Pixel aus Datei wieder geben
Da hast du völlig Recht. Ich habe mich hier nur daran erinnert, wie schwer es mir fiel mich nach ein paar Jahren Lernen mit typisierten Dateien an Streams zu gewöhnen. "File of ..." macht doch recht bequem (und unflexibel). Aber ja, das ist hier vermutlich zu hastig empfohlen gewesen. Hier langt es ja locker für Ergebnisse, und die sind es doch die zum Weitermachen motivieren :) (Der Rest kommt von selbst (und aus Dokus :mrgreen:))
|
AW: Pixel aus Datei wieder geben
Nicht ohne Grund habe ich dem Threadersteller BlockWrite/BlockRead empfohlen, denn typisierte Dateitypen sind unflexibel. Streams sind wohl noch sinnvoller, aber damit tue ich mich auch trotz jahrelanger Programmier-Erfahrung mitunter etwas schwer - zumal ich die vorigen Jahre nur wenig mit Delphi gemacht habe.
|
AW: Pixel aus Datei wieder geben
Ja das mit den anderen Dingen klingt recht spannend.
Aber wie gesagt wir sollen in den Programmen NUR dinge verwenden die unser Herr Prof. uns gezeigt hat alles andere lässt er nicht zu wie unsinnig das auch ist kann ich leider nicht beeinflussen |
AW: Pixel aus Datei wieder geben
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:49 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 by Thomas Breitkreuz