AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi JPG-Ressourcennutzung in eigenem kompilierten Programm

JPG-Ressourcennutzung in eigenem kompilierten Programm

Ein Thema von ScotsMan · begonnen am 10. Feb 2014 · letzter Beitrag vom 12. Feb 2014
Antwort Antwort
ScotsMan

Registriert seit: 1. Nov 2006
Ort: Leipzig
13 Beiträge
 
Delphi XE5 Professional
 
#1

JPG-Ressourcennutzung in eigenem kompilierten Programm

  Alt 10. Feb 2014, 21:01
Hi all,
nach langem Suchen und unter Verknüpfung verschiedener Beiträge aus den Foren hier bin ich endlich auf eine recht adrette (finde ich - Abkürzungen willkommen)
Lösung gekommen für ein Problem im Umgang mit JPEGs, welches ich hatte, gelöst habe und hier zugänglich machen möchte:

Hintergrund: Ich arbeite ab und an mit postum (also: nach dem Kompilieren) veränderten EXE-Dateien. Was wie pures hacking klingt, hat seinen Sinn: Wenn man z.B. eine Client-Server-Anwendung schreibt, dann sollte der Client-Installer Informationen (...IP) über seinen konkreten Server bekommen, wenn dieser installiert wird. Das Installieren des Servers macht aber schon der Programmnutzer - also muß mein Installer quasi "zur Laufzeit" modifiziert werden.
Ein anderes Beispiel, an dem ich gerade arbeite, ist "Pack & Go" - also, z.B. Jemandem eine Bildershow als _eine_ Datei mitzugeben.
Und da sind wir an der interessanten Stelle:

Ich packe eine EXE-Datei und ein (später x JPegs) JPeg zusammen in eine Datei. Für Windows ist das uninteressant, die Arbeit der EXE ist nicht beeinträchtigt, wenn sie an erster Stelle steht. Ich selbst aber weiß, daß mein Programm #xx# Byte lang ist, und das JPeg #yy# Byte. Jetzt möchte ich das JPeg in meinem Programm darstellen - wie kriege ich das aus der Datei wieder heraus? Und zwar natürlich, ohne schreibend auf die Festplatte zuzugreifen!

Das Beispielprogramm hier trägt aus der VCL nur einen Button und ein Image. Achtung: F9 gilt hier nicht! Nach(!) dem Kompilieren und VOR(!) jedem Ausführen muß man die EXE mit dem JPeg verlinken! Also nie aus der IDE heraus aufrufen! Ansonsten muß man in den ausführlich erklärten Code nur die beiden Zahlen #xx# und #yy# eintragen.

Ach so: In Wirklichkeit sollte man die Länge des JPEG besser an das Ende der Datei schreiben (z.B. als Cardinal), dann zuerst die 4 Byte auslesen und dann damit auf das Startbyte des JPeg springen, um von der Länge des Programmcodes unahängig zu sein. Das verkompliziert das Beispiel aber, deshalb habe ich darauf verzichtet... ebenso auf Sicherheiten, es geht hier nur um das Prinzip!

Have fun!
ScotsMan

Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Buttons;

type
  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    Image1: TImage;
    procedure BitBtn1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// OLE-Handling erfolgt über ActiveX-Steuerelemente
// diese werden hiermit eingebunden
uses axCtrls;

procedure TForm1.BitBtn1Click(Sender: TObject);
var aByteBuffer : Array of Byte;
    MyFileName : string;
    MyFilestream : TFileStream;
    MyFileSize : integer;
    ABitmap : TBitmap;
    OleG: TOleGraphic;
    MyOutStream : TMemoryStream;
begin
  // Dateieigenschaften
  // Name (ich selbst)
  MyFileName := ParamStr(0);
  //...Öffnen
  MyFileStream := TFileStream.create(MyFileName ,fmOpenRead or fmShareDenyNone);
  // Byteposition: Zahl der Bytes der Originaldatei
  MyFileStream.Position := #xx#;
  // Bytezahl: Größe des Bildes
  MyFileSize := #yy#;
  // Zwischenpuffer für das Bild in korrekter Größe einrichten
  SetLength(aByteBuffer, myFileSize);
  // Dateistreamfragment nach Bytepuffer einlesen
  MyFilestream.read( aByteBuffer[0], myFileSize);
  // Aufräumen: Datei schließen
  MyFilestream.free;
  // MemoryStream im Speicher anlegen
  MyOutStream := TMemoryStream.Create;
  // kompletten Puffer in MemoryStream schreiben
  MyOutStream.Write(aByteBuffer[0],myFileSize);
  // Aufräumen: Buffer freigeben
  SetLength(aByteBuffer, 0);
  // MemoryStream: Zeiger an den Anfang setzen
  MyOutstream.Position := 0;
  // TOLeGraphic ist in axCtrls ("grafischer Container ... für Bitmaps")
  OleG := TOleGraphic.Create;
  // Laden aus dem Memory Stream in den Container
  OleG.LoadFromStream(MyOutStream);
  // Aufräumen: MemoryStream freigeben
  MyOutStream.Free;
  // Neue Bitmap schaffen
  ABitmap := TBitmap.Create;
  // Parameter vom OLE-Container nehmen und zeichnen
  with ABitmap do
    begin
      Width := OleG.Width;
      Height := OleG.Height;
      Canvas.Draw(0,0,OleG);
    end;
  // Aufräumen: OLE-Container freigeben
  OleG.Free;
  // Bitmap in das Image (Standard-Control) übernehmen
  Image1.Picture.Bitmap.Assign(ABitmap);
  // Parameter des Bitmaps vom Original setzen
  Image1.Width := ABitmap.Width;
  Image1.Height := ABitmap.Height;
  // Aufräumen: Bitmap freigeben
  ABitmap.Free;
  // Image positionieren
  Image1.Top := 50;
  Image1.Left := 1;
  // fertig...
end;
$ route add default roma.it
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

AW: JPG-Ressourcennutzung in eigenem kompilierten Programm

  Alt 10. Feb 2014, 22:16
Warum legst du denn den Puffer aByteBuffer an?
Du kannst doch direkt vom FileStream in den MemoryStream kopieren.
MyOutStream.CopyFrom(MyFilestream, myFileSize);

Dein Code ist übrigens überkommentiert.
Du hast es sicher gutgemeint, aber ein Kommentar für jede einzelne Zeile ist zu viel.
Ich würde den Code lieber so aufbereiten, dass man eine Funktion mit Übergabeparametern hat die man aufrufen kann.
fork me on Github
  Mit Zitat antworten Zitat
ScotsMan

Registriert seit: 1. Nov 2006
Ort: Leipzig
13 Beiträge
 
Delphi XE5 Professional
 
#3

AW: JPG-Ressourcennutzung in eigenem kompilierten Programm

  Alt 12. Feb 2014, 11:44
Hallo, und Danke.

1.) Ja, thanks, der CopyFrom-Befehl erspart das Einrichten eines Puffers - gerade ausprobiert und ab sofort im Programm eingesetzt.

2.) Das Überkommentieren habe ich nur für die Darstellung hier gemacht, um evtl. auch Newbies zu zeigen, was wo passiert. Normalerweise sieht mein Quellcode weniger grün aus, "ischwöre"

ScotsMan
$ route add default roma.it
  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 17:44 Uhr.
Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2020 by Daniel R. Wolf