Copie d' une partie d' un TGraphic vers un Canvas avec option de transparence [Résolu]

Signaler
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
-
Messages postés
4199
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
-
Bonjour à tous,

je voudrais savoir s' il existe une méthode plus performante pour copier une partie d' un TGraphic vers un Canvas.

Pour l' instant, je passe par un TBitmap que je crée dynamiquement:
          if (MaxWidth <> aBgPicture.Picture.Width) or ((MaxHeight <> aBgPicture.Picture.Height))
          then begin
            // Copy part of the image :
            TmpBmp := TBitmap.Create;

            // Try converting into bitmap
            TmpBmp.Width  := MaxWidth;
            TmpBmp.Height := MaxHeight;
            TmpBmp.PixelFormat := pf32bit;
            aBgPicture.Picture.Graphic.Transparent := false;
            TmpBmp.Canvas.Draw(0, 0,  aBgPicture.Picture.Graphic);
            TmpBmp.Transparent := aBgPicture.Transparent;
            aCanvas.Draw(x, y,  TmpBmp);
            TmpBmp.Free;
          end
          else
            aCanvas.Draw(x, y,  aBgPicture.Picture.Graphic);

Merci,
Maurício

11 réponses

Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5
ReBonjour,

je vais vous donner la fonction que je viens de finaliser et qui marche très bien et pour tous les types d' images:

procedure DrawGraphic(onCanvas: TCanvas; x, y: Integer; Graphic: TGraphic; SrcRect: TRect; Transparent: Boolean);
var TmpBmp: TBitmap;
begin
  try
    TmpBmp := TBitmap.Create;
    TmpBmp.Width  := SrcRect.Right - SrcRect.Left;
    TmpBmp.Height := SrcRect.Bottom - SrcRect.Top;
    TmpBmp.PixelFormat := pf32bit;

    // Copy actual Canvas to the Bitmap.Canvas for transparent feature :
    if Transparent
    then begin
      TmpBmp.Canvas.CopyRect(classes.Rect(0, 0, TmpBmp.Width, TmpBmp.Height),  // Destination Rect
                              onCanvas, classes.Rect(x, y, x + TmpBmp.Width, y + TmpBmp.Height));
    end;

    TmpBmp.Canvas.Draw(0, 0,  Graphic);
    onCanvas.Draw(x, y,  TmpBmp);
  finally
    TmpBmp.Free;
  end;
end;
Messages postés
4199
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
29
procedure DrawGraphic(Canvas: TCanvas; const X,Y: Integer;
                      Graphic: TGraphic; const SrcRect: TRect;
                      const Transparent: Boolean);
var TmpBmp: TBitmap;
begin
  TmpBmp := TBitmap.Create;
  try
    TmpBmp.Width  := SrcRect.Right - SrcRect.Left;
    TmpBmp.Height := SrcRect.Bottom - SrcRect.Top;
    TmpBmp.PixelFormat := pf32bit;

    if Transparent then
      TmpBmp.Canvas.CopyRect(Rect(0, 0, TmpBmp.Width, TmpBmp.Height), 
                             Canvas,
                             Rect(x, y, x+TmpBmp.Width, y+TmpBmp.Height));

    TmpBmp.Canvas.Draw(0, 0,  Graphic);
    Canvas.Draw(x, y,  TmpBmp);
  finally
    TmpBmp.Free;
  end;
end;






Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5
Notez que TGraphic (aBgPicture.Picture) peut avoir plusieurs formats:
Bmp, metafile, jpeg, png etc ...
Messages postés
3810
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
28 mai 2020
29
j'ai peut être pas bien saisi ton problème donc je te propose aussi de regarder du coté TransparentBlt

voilà donc soit l'une où l'autre devrait convenir

 
@+
Cirec

<hr siz="" />
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5
Merci Cirec,

je vais jeter un oeil!
Après réflexion, je n' ai pas besoin de transparence dans mon cas ...
Ce que je veux c' est que ça marche avec tous les formats qui peuvent être dans le TGraphic.

Je vais généraliser la question :
je désire copier une partie d' une image (définie par un TRect) contenue dans un TGraphic vers un TCanvas.

Merci,
A+
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5
J' ai pensé au Bitblt() au départ ...
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5
Remarks

The TransparentBlt function works with compatible bitmaps (DDBs).


Celle ci ne marche qu' avec des bitmaps :(
Messages postés
3810
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
28 mai 2020
29
pour une copie complète ceci devrait suffir :
aCanvas.Draw(x, y,  aBgPicture.Picture.Graphic);

 
@+
Cirec

<hr siz="" />
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5
Bem justement, c' est ce que je fais pour l' instant (regarde dans le "else") :

if (MaxWidth <> aBgPicture.Picture.Width) or ((MaxHeight <> aBgPicture.Picture.Height))
          then begin
            // Copy part of the image :
            TmpBmp := TBitmap.Create;

            // Try converting into bitmap
            TmpBmp.Width  := MaxWidth;
            TmpBmp.Height := MaxHeight;
            TmpBmp.PixelFormat := pf32bit;
            aBgPicture.Picture.Graphic.Transparent := false;
            TmpBmp.Canvas.Draw(0, 0,  aBgPicture.Picture.Graphic);
            TmpBmp.Transparent := aBgPicture.Transparent;
            aCanvas.Draw(x, y,  TmpBmp);
            TmpBmp.Free;
          end
          else
            aCanvas.Draw(x, y,  aBgPicture.Picture.Graphic);

De plus, j' ai un autre problème pour les png sous Delphi 2009 :
en DesignTime, Picture.Graphic <> Nil fonctionne, mais en run-time non ...

A+
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5
"De plus, j' ai un autre problème pour les png sous Delphi 2009 :
en DesignTime, Picture.Graphic <> Nil fonctionne, mais en run-time non ..."

Ce problème est résolu en mettant "pngimage" dans les uses ...
A+
Messages postés
4199
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
29
<strike>Picture.Graphic <> Nil</strike>





Picture.Graphic.Empty





ensuite pour ta question :

Quand tu ouvre/charge une image, utilise un TBitmap en cache ou tu placera l'image dedans (quelle soit JPG, PNG, BMP ou autre.

soit:
Picture.LoadFromFile(...);
BMP.Width := Picture.Width;
BMP.Heihgt := Picture.Height;
BMP.PixelFormat := pf32bit;
BMP.Canvas.Draw(0,0,Picture.Graphic);

(PaintBox.Canvas / Self.Canvas).Draw(0,0,BMP);
(Image1.Picture.Bitmap).Assign(BMP);

on peu aussi travailler avec
StretchBlt

exemple :

SetStretchBltMode(PaintBox1.Canvas.Handle, HALFTONE);
StretchBlt(PaintBox1.Canvas.handle, 0, 0, MaxWidth, MaxHeight,
                BMP.Canvas.Handle, 0, 0, BMP.Width, BMP.Height,
                SRCCOPY);