Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Pixel aus Datei wieder geben (https://www.delphipraxis.net/172362-pixel-aus-datei-wieder-geben.html)

EMS 28. Dez 2012 18:00

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.

Klaus01 28. Dez 2012 18:11

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

EMS 28. Dez 2012 18:13

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?

delnu 28. Dez 2012 18:21

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}

EMS 28. Dez 2012 18:31

AW: Pixel aus Datei wieder geben
 
Super Danke das hat funktioniert

daywalker9 28. Dez 2012 18:50

AW: Pixel aus Datei wieder geben
 
Zitat:

Zitat von delnu (Beitrag 1196988)
Und ist das wirklich Delphi ?
Dann hieße es doch nicht {$R *.lfm} sondern {$R *.dfm}

Er nutzt Lazarus+FreePascal

delnu 28. Dez 2012 22:02

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:
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;
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.

Medium 29. Dez 2012 00:43

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.

Bummi 29. Dez 2012 00:50

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.

Medium 29. Dez 2012 02:04

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:))


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:47 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz