AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi x Bilder einheitlich skaliert auf drittes Bild zeichen

x Bilder einheitlich skaliert auf drittes Bild zeichen

Ein Thema von QStorm · begonnen am 19. Apr 2013 · letzter Beitrag vom 23. Apr 2013
Antwort Antwort
QStorm

Registriert seit: 28. Jun 2008
46 Beiträge
 
#1

x Bilder einheitlich skaliert auf drittes Bild zeichen

  Alt 19. Apr 2013, 11:38
Hallo,

Vorab, verzeiht mir, falls das Thema schon aufkam. Ich habe mit Hilfe der Suche kein passendes Thema gefunden. Folgendes Problem beschäftigt mich:

Ich habe Bilder in verschiedenen Formaten vorliegen (BMP, JPEG, PNG, GIF, ...). Die Bilder kommen teilweise aus einer Datenbank, aber auch aus anderen Quellen. Nun möchte ich diese Bilder proportional korrekt auf eine gemeinsame Größe skalieren und in einem Raster (NxM) auf ein drittes Bild zeichnen. Dabei soll die Transparenz der einzelnen Bilder berücksichtigt werden. Einige Bilder haben halb-transparente Farben (Alphakanal). Zudem haben die Ausgangsbilder unterschiedliche "Transparentfarben". Der Hintergrund, des Zielbildes (auf den die Bilder gezeichnet werden sollen) soll ebenfalls transparent sein.

Ich habe es mit verschiedenen Ansätzen versucht. Leider bin ich auf die folgenden Probleme gestoßen:
- "Canvas.StretchDraw" liefert eine sehr schlechte Qualität (die Skalierung eines TBitmaps habe ich schlussendlich auf andere Weise in akzeptabler Qualität hinbekommen)
- die Standardimplementierung von TBitmap unterstützt so wie es aussieht keine halb-transparenten Farben und auch nur BMP
- nachdem ich Bilder mit unterschiedlichen "Transparentfarben" auf das Zielbild gezeichnet habe, gab es Probleme mit der Transparenz

Habt ihr eine Idee/Ansatz, wie man das Problem lösen könnte?
Wenn möglich:
- ohne TImage
- ohne externe Lib

Vielen Dank im Voraus

Grüße
QStorm
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.534 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: x Bilder einheitlich skaliert auf drittes Bild zeichen

  Alt 19. Apr 2013, 11:44
Für das Skalieren hätte ich da was, aber dabei geht wohl die Transparenz flöten.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
QStorm

Registriert seit: 28. Jun 2008
46 Beiträge
 
#3

AW: x Bilder einheitlich skaliert auf drittes Bild zeichen

  Alt 19. Apr 2013, 12:49
Ich habe mal einen sehr einfachen Beispielcode implementiert. Bitte beachtet die Dateipfade anzupassen bevor ihr ihn ausführt.
Angehängte Dateien
Dateityp: zip Images - 2013.04.19 - 12.45.00.zip (9,9 KB, 9x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#4

AW: x Bilder einheitlich skaliert auf drittes Bild zeichen

  Alt 19. Apr 2013, 14:09
Um das ganze in guter Qualität hinzubekommen könntest Du auf GDI+ zurückgreifen,da Du aber nichts externes wolltest und TImage vermeiden willst, hätte ich folgendes anzubieten.
Delphi-Quellcode:
unit Demop;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  ENotImplemeted=Class(Exception);

  TForm3 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

uses Math, pngImage, GifImg,jpeg;

Procedure SetCanvasZoomAndRotation(ACanvas: TCanvas; Zoom: Double; Angle: Double; CenterpointX, CenterpointY: Double);
var
  form: tagXFORM;
  Winkel: Double;

begin
  Winkel := DegToRad(Angle);
  SetGraphicsMode(ACanvas.Handle, GM_ADVANCED);
  SetMapMode(ACanvas.Handle, MM_ANISOTROPIC);
  form.eM11 := Zoom * cos(Winkel);
  form.eM12 := Zoom * Sin(Winkel);
  form.eM21 := Zoom * (-Sin(Winkel));
  form.eM22 := Zoom * cos(Winkel);
  form.eDx := CenterpointX;
  form.eDy := CenterpointY;
  SetWorldTransform(ACanvas.Handle, form);
end;

Procedure LoadAndPaint(FileName: String; C: TCanvas; x, y, BH: Integer;BitMapTransparent:Boolean=false);
var
  G: TGraphic;
  SC: Integer;
begin
  if UpperCase(ExtractFileExt(FileName)) = '.PNGthen
    G := TPngImage.Create
  else if UpperCase(ExtractFileExt(FileName)) = '.BMPthen
    begin
      G := TBitMap.Create;
      if BitMapTransparent then TBitMap(G).Transparent := true;
    end
  else if UpperCase(ExtractFileExt(FileName)) = '.GIFthen
    G := TGifImage.Create
  else if (UpperCase(ExtractFileExt(FileName)) = '.JPG') or (UpperCase(ExtractFileExt(FileName)) = '.JPEG') then
    G := TJpegImage.Create
  else raise ENotImplemeted.Create('Nicht berücksichtigtes Dateiformat');

  try
    G.LoadFromFile(FileName);
    SC := G.Width;
    if G.Height > G.Width then
      SC := G.Height;
    SetCanvasZoomAndRotation(C, BH / SC, 0, x, y);
    C.Draw(0, 0, G);
    SetCanvasZoomAndRotation(C , 1, 0, 0,0);
  finally
    G.Free;
  end;
end;

procedure TForm3.Button1Click(Sender: TObject);
Const
  C_Raster = 40;
var
  x, y: Integer;
  Path: String;
begin
  Path := IncludeTrailingBackSlash(ExtractFilePath(Paramstr(0)));
  x := 0;
  y := 0;
  LoadAndPaint(Path + '01.png', Canvas, x, y, C_Raster);
  Inc(x, C_Raster);
  LoadAndPaint(Path + '02.png', Canvas, x, y, C_Raster);
  Inc(x, C_Raster);
  LoadAndPaint(Path + '01.bmp', Canvas, x, y, C_Raster);
  Inc(y, C_Raster);
  Inc(x, C_Raster);
  LoadAndPaint(Path + '01.gif', Canvas, x, y, C_Raster);
  Inc(y, C_Raster);
  Inc(x, C_Raster);
  LoadAndPaint(Path + 'bbok.bmp', Canvas, x, y, C_Raster,true);

end;

end.
Miniaturansicht angehängter Grafiken
divgraph.png  
Angehängte Dateien
Dateityp: zip PaintDiv.zip (124,4 KB, 11x aufgerufen)
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
QStorm

Registriert seit: 28. Jun 2008
46 Beiträge
 
#5

AW: x Bilder einheitlich skaliert auf drittes Bild zeichen

  Alt 22. Apr 2013, 09:14
Um das ganze in guter Qualität hinzubekommen könntest Du auf GDI+ zurückgreifen,da Du aber nichts externes wolltest und TImage vermeiden willst, hätte ich folgendes anzubieten.
Vielen Dank für die Antworten.

@Bummi: Ich habe dein Beispiel ausprobiert. Es funktioniert wunderbar, mit einer Einschränkung: Wenn man die PNGs rotiert (z.B.: um 25°) dann wird die Transparenzfarbe auf das Canvas gezeichnet (die Transparenz geht verloren). Hast du eine Idee woran das liegen könnte?

/QStorm
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#6

AW: x Bilder einheitlich skaliert auf drittes Bild zeichen

  Alt 22. Apr 2013, 10:26
Darauf hatte ich gar nicht geachtet, da von Rotation ursprünglich keine Rede war.
Mit einem Umweg über ein Bitmap geht es:

Delphi-Quellcode:
Procedure LoadAndPaint(FileName: String; C: TCanvas; x, y, BH: Integer;BitMapTransparent:Boolean=false);
var
  G,G2: TGraphic;
  SC: Integer;
begin
  if UpperCase(ExtractFileExt(FileName)) = '.PNGthen
  begin
    G := TPngImage.Create;
  end
  else if UpperCase(ExtractFileExt(FileName)) = '.BMPthen
    begin
      G := TBitMap.Create;
      if BitMapTransparent then TBitMap(G).Transparent := true;
    end
  else if UpperCase(ExtractFileExt(FileName)) = '.GIFthen
    G := TGifImage.Create
  else if (UpperCase(ExtractFileExt(FileName)) = '.JPG') or (UpperCase(ExtractFileExt(FileName)) = '.JPEG') then
    G := TJpegImage.Create
  else raise ENotImplemeted.Create('Nicht berücksichtigtes Dateiformat');

  G2 := TBitmap.Create;
  try
    G.LoadFromFile(FileName);
    G2.Assign(G);
    G2.Transparent := BitMapTransparent;
    SC := G.Width;
    if G.Height > G.Width then
      SC := G.Height;
    SetCanvasZoomAndRotation(C, BH / SC, 0, x, y);
    C.Draw(0, 0, G2);
    SetCanvasZoomAndRotation(C , 1, 0, 0,0);
  finally
    G.Free;
    G2.Free;
  end;
end;
Angehängte Dateien
Dateityp: zip Demo.zip (44,5 KB, 6x aufgerufen)
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
QStorm

Registriert seit: 28. Jun 2008
46 Beiträge
 
#7

AW: x Bilder einheitlich skaliert auf drittes Bild zeichen

  Alt 23. Apr 2013, 08:46
Darauf hatte ich gar nicht geachtet, da von Rotation ursprünglich keine Rede war.
Mit einem Umweg über ein Bitmap geht es:
Die Rotation ist in den meisten Fällen auch nicht nötig, daher hatte ich sie nicht erwähnt. Mit dieser Lösung funktioniert es. Ich habe jetzt nur noch ein Problem:

Das Ergebnis der "Bilderzusammenstellung" soll ein TBitmap sein (oder ein anderer Untertyp von TGraphic). Das TBitmap muss ich in einigen Fällen einen TPicture zuweisen (pic.Bitmap.Assign(bit)), um es in bestimmten Komponenten (z.B.: cxGrid) nutzen zu können. Ich habe mal dein Beispiel dahingehend angepasst. Leider habe ich dann wieder Probleme mit der Transparenz. Dazu kommt, dass sich die Transparenz bei verschiedenen Komponenten (TPaintBox, TImage, TForm) unterschiedlich verhält.

Vermutlich liegt es an irgendeiner Einstellung. Leider finde ich sie nicht.

Noch eine allgemeine Frage:
Welche externe Bildverarbeitungs-Bibliothek könnt ihr empfehlen? Wenn möglich eine kommerzielle. Ich habe hier schon von GDI+ gehört. Graphics32 und ImageEn habe ich mal kurz überflogen. Leider hat Graphics32 keine geeignete Lizenz.
Wichtig ist, dass die Bibliothek ohne Probleme in kommerziellen Produkten einsetzbar/integrierbar ist.

Vielen Dank nochmal!

/QStorm
Angehängte Dateien
Dateityp: zip Demo2 - 2013.04.23 - 08.44.29.zip (45,1 KB, 5x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#8

AW: x Bilder einheitlich skaliert auf drittes Bild zeichen

  Alt 23. Apr 2013, 11:01
Ja, hier kommen wir jetzt an den Punkt wo man mit reinen GDI-Routinen Probleme bekommt.
Ich meine ich hatte in meiner ersten Antwort auf GDI+ hingewiesen, hier entfallen alle Basteleien ...
Ich verwende noch die anscheinend nicht erhältliche Api von http://www.progdigy.com/.
Eine freie Implementierung, mit der ich noch keine Erfahrung habe gibt es unter http://www.bilsen.com/gdiplus/index.shtml, hier sind auch weitere Downloadadressen angegeben.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  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 02:47 Uhr.
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