Entwickler-Ecke

Multimedia / Grafik - Grafiken skalieren


galagher - Di 02.11.10 14:54
Titel: Grafiken skalieren
Hallo!

Ich habe folgenden Code zum Skalieren von Grafiken, so kann man aber nur von grösser auf kleiner skalieren, zB. um Thumbnails zu erhalten. Was muss ich ändern, um auch von kleiner auf grösser skalieren zu können?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
procedure TLabeledImage.ScaleImage(aWidth, aHeight: Integer);
var
  W, H: Double;
  L, T: Integer;
  aRect: TRect;
  aImage: TImage;
begin
 aImage := TImage.Create(Self);

 aImage.Canvas.Brush.Color := FColor;
 aImage.Canvas.FloodFill(00, FColor, fsBorder);

 W := Picture.Width;
 H := Picture.Height;

 //Skalieren von grösser auf kleiner
 while (W > aWidth) or (H > aHeight) do
 begin
  W := W / 1.01;
  H := H / 1.01;
 end;

 //Hier skalieren von kleiner auf grösser, aber wie ???


 L := aWidth+1;
 T := aHeight+1;

 L := L mod Trunc(W) div 2;
 T := T mod Trunc(H) div 2;

 aRect := Rect(L, T, Trunc(W)+L, Trunc(H)+T);

 aImage.Canvas.CopyMode := cmSrcCopy;
 aImage.Canvas.StretchDraw(aRect, Picture.Graphic);

 Picture := aImage.Picture;

 Width := aRect.Right;
 Height := aRect.Bottom;

 aImage.Free;
end;


Vielleicht ist die Lösung ja ganz einfach, ich weiss es wirklich nicht!
Habe auch schon gegoogelt, aber da gibt's vor allem Code zum Skalieren von Bitmaps, ich möchte aber jedes Format verarbeiten können!


bummi - Di 02.11.10 15:15

Schau mal unter
http://www.delphipraxis.net/155428-quadratische-thumbnails-erstellen.html


Gausi - Di 02.11.10 15:19

Und warum nimmst du den Bitmap-Code nicht? Die Lösung mit dem TImage hier ist doch noch mehr Murks, und wandelt auch alles intern in Bitmaps um. Und sowas

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
//Skalieren von grösser auf kleiner
 while (W > aWidth) or (H > aHeight) do
 begin
  W := W / 1.01;
  H := H / 1.01;
 end;

Lässt sich auch direkt berechnen, da muss man sich nur mal kurz hinsetzen, etwas rechnen und ggf. ein paar Fälle unterscheiden. ;-)

Im Zweifel das "/" an der Stelle einfach durch ein "*" ersetzen, dann sollte das Bild größer werden. ;-)


galagher - Di 02.11.10 15:54

user profile iconGausi hat folgendes geschrieben Zum zitierten Posting springen:
Und warum nimmst du den Bitmap-Code nicht?
Weil ich bei den Grafikformaten flexibel sein möchte und nicht nur Bitmaps bearbeiten will!
user profile iconGausi hat folgendes geschrieben Zum zitierten Posting springen:
Die Lösung mit dem TImage hier ist doch noch mehr Murks, und wandelt auch alles intern in Bitmaps um.
Warum Murks und wo Bitmaps? Siehe auch hier: http://www.delphi-forum.de/viewtopic.php?p=469135

user profile iconGausi hat folgendes geschrieben Zum zitierten Posting springen:
Im Zweifel das "/" an der Stelle einfach durch ein "*" ersetzen, dann sollte das Bild größer werden. ;-)
Habe ich zuerst auch gedacht, das bewirkt aber nur, dass die Grafik die Vorgabewerte der Komponente annimmt, ich weiss aber nicht, woran das liegt.


Gausi - Di 02.11.10 17:13

Murks deswegen, weil hier eine visuelle Komponente (TImage) zur Datenverarbeitung mißbraucht wird. Das ist in etwa so, als würdest du ein unsichtbares Edit auf die Form knallen, um einen String zu speichern, oder ein TMemo, um ein paar Strings zu sortieren. :nixweiss:
Für beliebige Formate gibt es dann TPicture bzw TGraphic - das ist das, was in TImage ja auch verwendet wird. Aber afaik hast du Bitmap-Daten im Speicher, sobald du damit arbeitest. Auf das Quellformat kommt es da nicht an. (Aber da kann ich mich auch irren)

Zu dem / bzw. *: Hast du dann auch den Schleifenkopf abgeändert? Da muss dann ja das > durch ein < ersetzt werden.


platzwart - Di 02.11.10 17:39

Mit einer TBitmap kann man nicht nur .bmp Dateien verarbeiten, sondern auch jpeg etc... Aber diese Komponente ist nicht-visuell und somit deutlich performanter. Und bei dieser While-Schleife stellen sich einem alle Haare zu Berge, das kann man auch einfach mit einer Zeile berechnen ;)


galagher - Di 02.11.10 17:44

user profile iconGausi hat folgendes geschrieben Zum zitierten Posting springen:
Für beliebige Formate gibt es dann TPicture bzw TGraphic
Werde dann den Code entsprechend anpassen, mal sehen!

user profile iconGausi hat folgendes geschrieben Zum zitierten Posting springen:
Zu dem / bzw. *: Hast du dann auch den Schleifenkopf abgeändert? Da muss dann ja das > durch ein < ersetzt werden.
Ja, habe ich, klappt aber nicht!

user profile iconplatzwart hat folgendes geschrieben Zum zitierten Posting springen:
Mit einer TBitmap kann man nicht nur .bmp Dateien verarbeiten, sondern auch jpeg etc... Aber diese Komponente ist nicht-visuell und somit deutlich performanter. Und bei dieser While-Schleife stellen sich einem alle Haare zu Berge, das kann man auch einfach mit einer Zeile berechnen ;)
Hm... :?


galagher - Di 02.11.10 19:03

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Schau mal unter
http://www.delphipraxis.net/155428-quadratische-thumbnails-erstellen.html
Stichwort "ScaleImage": Habe nach allen Dateien gegoogelt und erstellt - Fazit: Klappt leider nicht. Trotzdem danke!


bummi - Di 02.11.10 20:01

wieso unter Qualitätsverlust:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
Procedure DrawGraphicToCanvas(Graphic:TGraphic;Canvas:TCanvas;Destrect:TRect);
var
    x,y,x1,y1:Double;
    Arect:TRect;
begin
      y:=Graphic.Height;
      x:=Graphic.Width;
      y1:=y/(Destrect.Right-Destrect.Left);
      x1:=x/(Destrect.Bottom-Destrect.Top);
      if x1<y1 then x1:=y1 ;
      x:=x/x1;
      y:=y/x1;
      Arect.left:=Destrect.Left+((Destrect.Right-Destrect.Left)-round(x)) div 2 ;
      Arect.top:=Destrect.Top+((Destrect.Bottom-Destrect.Top)-round(y)) div 2;
      Arect.right:=Arect.left+round(x);
      Arect.bottom:=Arect.top+round(y);
      Canvas.Fillrect(Destrect);
      Canvas.stretchdraw(Arect,Graphic);
end;


Procedure DrawBMPToCanvas(bmp:TBitmap;Canvas:TCanvas;Destrect:TRect);
var
    x,y,x1,y1:Double;
    Arect:TRect;
begin
      y:=bmp.Height;
      x:=bmp.Width;
      y1:=y/(Destrect.Right-Destrect.Left);
      x1:=x/(Destrect.Bottom-Destrect.Top);
      if x1<y1 then x1:=y1 ;
      x:=x/x1;
      y:=y/x1;
      Arect.left:=Destrect.Left+((Destrect.Right-Destrect.Left)-round(x)) div 2 ;
      Arect.top:=Destrect.Top+((Destrect.Bottom-Destrect.Top)-round(y)) div 2;
      Arect.right:=Arect.left+round(x);
      Arect.bottom:=Arect.top+round(y);
      Canvas.Fillrect(Destrect);
      Canvas.stretchdraw(Arect,bmp);
end;



ansonsten halt ScaleImage aus meinen ersten Post

Du brauchst hierfür GDI+ von http://www.progdigy.com/


galagher - Di 02.11.10 20:17

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
wieso unter Qualitätsverlust:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
Procedure DrawGraphicToCanvas(Graphic:TGraphic;Canvas:TCanvas;Destrect:TRect);
var
    x,y,x1,y1:Double;
    Arect:TRect;
begin
      y:=Graphic.Height;
      x:=Graphic.Width;
      y1:=y/(Destrect.Right-Destrect.Left);
      x1:=x/(Destrect.Bottom-Destrect.Top);
      if x1<y1 then x1:=y1 ;
      x:=x/x1;
      y:=y/x1;
      Arect.left:=Destrect.Left+((Destrect.Right-Destrect.Left)-round(x)) div 2 ;
      Arect.top:=Destrect.Top+((Destrect.Bottom-Destrect.Top)-round(y)) div 2;
      Arect.right:=Arect.left+round(x);
      Arect.bottom:=Arect.top+round(y);
      Canvas.Fillrect(Destrect);
      Canvas.stretchdraw(Arect,Graphic);
end;
/

Folgender Aufruf:

Delphi-Quelltext
1:
DrawGraphicToCanvas(LabeledImage1.Picture.Graphic, LabeledImage1.Canvas, Rect(0,0,1024,768));                    

... klappt mit einem jpg nicht: "Bild kann nur geändert werden, wenn es ein Bitmap enthält."

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Du brauchst hierfür GDI+ von http://www.progdigy.com/
Ich möchte, wenn möglich, nichts extra installieren, ich will doch nur ein Bild skalieren... :(


bummi - Di 02.11.10 20:32

Seltsam, ich habe es mit einem JPG getestet, geht problemlos....
hast jpeg in den uses drin??

Installieren muß Du für GDI+ nichts, einfach die 4 Dateien in einen Ordner legen der im Delphisuchpfad liegt


galagher - Di 02.11.10 21:01

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Seltsam, ich habe es mit einem JPG getestet, geht problemlos....
hast jpeg in den uses drin??Ja, habe ich.

Installieren muß Du für GDI+ nichts, einfach die 4 Dateien in einen Ordner legen der im Delphisuchpfad liegt
Ok, habe es mir zugegebenermassen nicht näher angesehen!


galagher - Di 02.11.10 22:04

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Installieren muß Du für GDI+ nichts, einfach die 4 Dateien in einen Ordner legen der im Delphisuchpfad liegt
Habe ich jetzt gemacht und - was soll ich sagen - es funktioniert bestens!
Vielen Dank, genau, was ich brauche! :D


galagher - Do 04.11.10 11:15

user profile iconGausi hat folgendes geschrieben Zum zitierten Posting springen:
Und sowas

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
//Skalieren von grösser auf kleiner
 while (W > aWidth) or (H > aHeight) do
 begin
  W := W / 1.01;
  H := H / 1.01;
 end;

Lässt sich auch direkt berechnen, da muss man sich nur mal kurz hinsetzen, etwas rechnen und ggf. ein paar Fälle unterscheiden. ;-)

Da direkte Berechnung den Code schneller macht - davon gehe ich aus, wenn die while-Schleife wegfällt - wüsste ich gerne, wie! Habe leider keine Idee, wie eine Berechnungsformel dazu aussehen könnte, bin also gespannt auf eure Infos!


bummi - Do 04.11.10 12:33

http://www.delphipraxis.net/155428-quadratische-thumbnails-erstellen.html
Posting #3


galagher - Do 04.11.10 18:37

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
http://www.delphipraxis.net/155428-quadratische-thumbnails-erstellen.html
Posting #3

Hallo!
Es funktioniert mit bmp's, aber nicht mit jpg's. Andere Formate habe ich noch nicht getestet.
Ohne die Anweisung "Image1.Picture.Bitmap := nil" bleibt das Bild in Originalgrösse erhalten, das verkleinerte Bild wird in der linken oberen Ecke "darüber"gezeichnet. Ist die Anweisung aktiv, wird gar nichts gezeichnet.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.Button1Click(Sender: TObject);
var
   zielrect : TRect;
begin
   zielrect := Rect(006363); // Grösse Thumbnail
   MaintainAspectRatio(zielrect, Image1.Picture.Bitmap.Width,
    Image1.Picture.Bitmap.Height, True);
   // jetzt ist zielrect so geändert, dass man das Bitmap mit StrechDraw
   // ohne Änderung des Seitenverhältnisses verkleinern kann

 //Ohne diese Anweisung bleibt das Bild in Originalgrösse erhalten
 //und das verkleinerte Bild wird links oben gezeichnet.
 //Mit dieser Anweisung wird gar nichts gezeichnet.
 Image1.Picture.Bitmap := nil;

 Image1.Picture.Bitmap.Canvas.StretchDraw(zielrect,
  Image1.Picture.Bitmap);
end;


bummi - Do 04.11.10 18:49

Ich hatte eigentlich von Procedure ScaleImage im Posting 3 gespreochen
und das

Delphi-Quelltext
1:
2:
Image1.Picture.Bitmap.Canvas.StretchDraw(zielrect,
  Image1.Picture.Bitmap);

kann ja nur Käse ergeben....


galagher - Do 04.11.10 19:31

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Ich hatte eigentlich von Procedure ScaleImage im Posting 3 gespreochen

Habe da wohl etwas überlesen oder verwechselt oder beides... :oops:
Naja, ScaleImage hat aber den Nachteil, dass man Dateinamen angeben muss. Ich möchte aber eine Grafik als solche in einem TImage ändern und dann im selben TImage verkleinert oder vergrössert (also skaliert) ausgeben, wobei sich das TImage den neuen Abmessungen anpasst. In ScaleImage ist die Variable image vom Typ TGPImage, welches Dateinamen erfordert. Ich weiss nicht, wie ich ScaleImage so umschreiben kann, dass ich es ohne Quell- und Zieldateinamen verwenden kann.

Leider weiss ich auch nicht, wie man meinen Code hier vereinfachen kann:

Delphi-Quelltext
1:
2:
3:
4:
5:
 while (W > aWidth) or (H > aHeight) do
 begin
  W := W / 1.01;
  H := H / 1.01;
 end;


user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
und das

Delphi-Quelltext
1:
2:
Image1.Picture.Bitmap.Canvas.StretchDraw(zielrect,
  Image1.Picture.Bitmap);

kann ja nur Käse ergeben....

Es klappt aber bei Bitmaps!


bummi - Do 04.11.10 20:36

Also jetzt ultimativ vorgekaut und optimiert für Deine Bedürfnisse

sehr gute Skalierungsqualität


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,GDIPAPI,GDIPOBJ, StdCtrls, jpeg, ExtCtrls,ActiveX;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Button1: TButton;
    Image2: TImage;
    procedure Button1Click(Sender: TObject);
  private
  public
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}

// 20101104 by Thomas Wassermann AKA Bummi www.explido-software.de
// hochwertige Skalierungen von TBitmap und TGraphic
Procedure ScaleImage(source:TGraphic;dest:TCanvas;DestRect:Trect;Center:Boolean=true);overload;
var
  graphics : TGPGraphics;
  image: TGPImage;
  width, height: Integer;
  faktor:Double;
  STR : TMemoryStream;
  X, Y:Double;
begin
  STR := TMemoryStream.Create;
  source.SaveToStream(STR);
  STR.Position := 0;
  image:= TGPImage.Create(TStreamAdapter.Create(Str));
  try
  width := image.GetWidth;
  height := image.GetHeight;
  if ((DestRect.Right - DestRect.Left) / width) < ((DestRect.Bottom -DestRect.Top)/Height) then faktor := (DestRect.Right - DestRect.Left) / width else faktor:= ((DestRect.Bottom -DestRect.Top)/Height);
  Faktor := ABS(Faktor);
  if Center then
      begin
        X := ((Destrect.Right - Destrect.Left) - faktor * width ) / 2;
        Y := ((Destrect.Bottom - Destrect.Top) - faktor * Height ) / 2;
      end
  else
      begin
        X := Destrect.Left;
        Y := Destrect.Top;

      end;
  graphics := TGPGraphics.Create(dest.Handle);
  try
    graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);
    graphics.DrawImage( image, MakeRect(X, Y , faktor * width, faktor * height),  00, width,  height, UnitPixel);
  finally
    graphics.Free;
  end;
  finally
  STR.Free;
  image.Free;
  end;
end;



procedure TForm1.Button1Click(Sender: TObject);
begin
 ScaleImage(image1.Picture.Graphic,Canvas,Rect(0,0,200,200));
 ScaleImage(image2.Picture.Bitmap,Canvas,Rect(200,200,400,400));
end;

end.


galagher - Do 04.11.10 21:23

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Button1Click(Sender: TObject);
begin
 ScaleImage(image1.Picture.Graphic,Canvas,Rect(0,0,200,200));
 ScaleImage(image2.Picture.Bitmap,Canvas,Rect(200,200,400,400));
end;

Vielen Dank für deine Hilfe, ich verstehe nur nicht, warum das hier nicht funktioniert:

Delphi-Quelltext
1:
ScaleImage(Image1.Picture.Graphic, Image1.Canvas, Rect(0,0,200,200));                    


Wenn ich mit 2 Images arbeite, wird nur der linke obere Ausschnitt dargestellt, der in das Rechteck passt:

Delphi-Quelltext
1:
ScaleImage(Image1.Picture.Graphic, Image2.Canvas, Rect(0,0,200,200));                    


Ich möchte aber eigentlich nicht irgendwo auf Form1.Canvas oder in einem zweiten Image zeichnen, sondern im Quell-Image.
Sorry, aber ich hab's nicht wirklich so mit Grafik...


bummi - Do 04.11.10 21:45

Ok, das Verständnisproblem liegt viel tiefer.

TImage ist eine Graphiccontrol dem etweder ein Bitmap oder ein TgraphicObjekt zugewiesen werden kann. Es mal sich dann selbst mit dem entsprechenden Objekt.
In dem Momemt in dem Du aus das Canvas zugreifen willst muß entweder ein Bitmap als Objekt vorhanden sein oder nichts (das wird dann von TImage intern erstellt).
Faktisch gemalt wird immer auf dem TBitmap des Image welches dieses dann auf seinem Canvas "malt".

Das bild wird von meiner Routine immer komplett in das gewählte Rechteck gemalt, wenn das TImage in welches Du malen möchtest kleiner ist als das Rechteck siehst Du freilich hiervon nicht alles.

Die Prozedur bekommt nur das Canvas übergeben und hat keine Ahnund davon ob Du auf eine Form, in ein TImage , auf den Drucker oder was auch immer ausgeben willst.
Die Verantwortung für die Größe des Zeichenbereiches liegt bei Dir.


galagher - Fr 05.11.10 09:29

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Das bild wird von meiner Routine immer komplett in das gewählte Rechteck gemalt, wenn das TImage in welches Du malen möchtest kleiner ist als das Rechteck siehst Du freilich hiervon nicht alles.
Es ist ja aber gar nicht kleiner, sondern als Quell-Grafik grösser und soll kleiner skaliert werden, daher müsste das hier doch klappen, tut es aber nicht:

Delphi-Quelltext
1:
ScaleImage(Image1.Picture.Graphic, Image1.Canvas,Rect(0,0,200,200));                    

Ich würde das so übersetzen: "Nimm die Grafik aus Image1 und male sie skaliert auf Image1.Canvas".

Wenn du sagst:
user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Die Prozedur bekommt nur das Canvas übergeben und hat keine Ahnund davon ob Du auf eine Form, in ein TImage , auf den Drucker oder was auch immer ausgeben willst.
Die Verantwortung für die Größe des Zeichenbereiches liegt bei Dir.
... dann müsste der obige Code doch funktionieren, oder? Denn die Prozedur weiss ja nicht, worauf gemalt werden soll. Demnach sollte sie auch auf die Canvas der Quell-Komponente malen. Macht sie aber nicht.

Der Hintergrund meiner Überlegungen ist praktischer Natur: Ich habe eine Komponente TLabeledImage, die mit meinem (langsamen) Code Grafiken skaliert. Ich suche nun eine Verbesserung. In meinem Programm werden zuerst in zur Laufzeit dynamisch erzeugten TLabeledImage's Grafikdateien geladen und dann gleich skaliert:

Delphi-Quelltext
1:
2:
 LabeledImage1.Picture.LoadFromFile(OpenPictureDlg1.Files[i]);
 LabeledImage1.ScaleImage(77102);  //diese Parameter geben Höhe und Breite an

Naja, und das möchte ich halt schneller haben, aber eben genauso: Im selben Image skaliert malen, nicht woanders, so dass man dann auf der Programmoberfläche (genauer auf einer ScrollBox) beliebig viele (= je nachdem, wie viele Dateien man lädt) Thumbnails hat. Diese Thumbnails müssen aber Komponenten vom Typ TLabeledImage sein - eben jene, in denen die Dateien geladen wurden und deren Grafiken jetzt skaliert sind!


bummi - Fr 05.11.10 10:12

Probiers einfach mal mit einem TBitmap,
für Scaleimage aus
rufe TImage1.invalidate aus
für nochmals Scvaleimage aus
rufe TImage1.invalidate aus

(Bild in Bild In Bild...)

Bei TGraphic geht wie gesagt gar nichts da TImage bereits mit eine TGraphicobjekt belegt ist und kein TBitmap anlegt welches für das Zeichen auf dem Canvas nötig wäre (hierbei würde ja dann auch Dein TGraphicobjekt entladen werden)

dann siehst Du was intern passiert.
Die Komponente wie Du sie bastelst kann nicht funktionieren.

Leite Deine Komponente von TGraphicControl ab
erzeige im Contructor ein TImage
füge eine Property Picture ein , reich hierbei Picture an Dein internes Image durch
Im Paint Deines GraphicControls kannst Du dann Scaleimage deines Internen TImage auf das Canvas Deinen TGraphiccontrols durchführen.


galagher - So 07.11.10 17:41

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Probiers einfach mal mit einem TBitmap,
für Scaleimage aus
rufe TImage1.invalidate aus
für nochmals Scvaleimage aus
rufe TImage1.invalidate aus

(Bild in Bild In Bild...)
Ja:

Delphi-Quelltext
1:
2:
 ScaleImage(
  image1.Picture.Graphic, image1.Canvas, rect(00200200));
...Bild in Bild in Bild - genau das möchte ich aber nicht, ich möchte in jenem Image skalieren, das die Ursprungsgrafik enthält, ohne das das Originalbild sochtbar bleibt!

Ausserdem funktioniert der Code nicht, wenn die Ursprungsgrafik kein Bitmap ist: "Bild kann nur geändert werden, wenn es ein Bitmap enthält."

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Bei TGraphic geht wie gesagt gar nichts da TImage bereits mit eine TGraphicobjekt belegt ist und kein TBitmap anlegt welches für das Zeichen auf dem Canvas nötig wäre (hierbei würde ja dann auch Dein TGraphicobjekt entladen werden)
Das verstehe ich nun überhaupt nicht! :nixweiss:

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Die Komponente wie Du sie bastelst kann nicht funktionieren.
Sie funktioniert, und zwar mit jedem Grafikformat und kann grösser und kleiner skalieren, aber der Code ist langsamer. Ich komme aber auf keine effizientere Formel zum Skalieren als die while-Schleifen mit den Divisionen.

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Leite Deine Komponente von TGraphicControl ab
erzeige im Contructor ein TImage
füge eine Property Picture ein , reich hierbei Picture an Dein internes Image durch
Im Paint Deines GraphicControls kannst Du dann Scaleimage deines Internen TImage auf das Canvas Deinen TGraphiccontrols durchführen.
Das ist mir jetzt aber auch zuviel Aufwand!

Vielen Dank für deine Hilfe, aber wenn dein Code wirklich auf das Bitmap-Format beschränkt ist, ist er doch nur sehr begrenzt nutzbar! Ich glaube aber, dass das doch nicht sein kann, und dass ich da sicher etwas nicht verstehe.

Ich suche einfach eine bessere, schnellere Formel für das hier:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
//...
 while (W > aWidth) or (H > aHeight) do
  begin
   W := W / 1.01;
   H := H / 1.01;
  end
else
  while (W < aWidth) or (H < aHeight) do
  begin
   W := W * 1.01;
   H := H * 1.01;
  end;