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

Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
- - Dernière réponse : f0xi
Messages postés
4304
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
9 mars 2018
- 4 mai 2009 à 17:14
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
Afficher la suite 

Votre réponse

12 réponses

Meilleure réponse
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
3
Merci
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;

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 104 internautes ce mois-ci

Commenter la réponse de cs_MAURICIO
Messages postés
4304
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
9 mars 2018
3
Merci
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;






Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 104 internautes ce mois-ci

Commenter la réponse de f0xi
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
0
Merci
Notez que TGraphic (aBgPicture.Picture) peut avoir plusieurs formats:
Bmp, metafile, jpeg, png etc ...
Commenter la réponse de cs_MAURICIO
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
3 août 2018
0
Merci
Salut,

regarde mon dernier code :
http://www.delphifr.com/codes/BITMAP-32BITS-INTEGRE-VCL-TIMAGE-TPICTURE-TBITMAP-TOPENPICTUREDIALOG_49861.aspx

pour un exemple d'utilisation de la fonction AlphaBlend .... elle fait exactement ce que tu demandes ...

si tu doutes ... dans mon code démo j'affiche un bitmap32 (donc vraie transparence) sur un JPEG sans le convertir avant en BMP !!!

cette fonction se fout du format elle demande un DC source et un DC Dest

 
@+
Cirec

<hr siz="" />
Commenter la réponse de Cirec
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
3 août 2018
0
Merci
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="" />
Commenter la réponse de Cirec
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
0
Merci
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+
Commenter la réponse de cs_MAURICIO
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
0
Merci
J' ai pensé au Bitblt() au départ ...
Commenter la réponse de cs_MAURICIO
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
0
Merci
Remarks

The TransparentBlt function works with compatible bitmaps (DDBs).


Celle ci ne marche qu' avec des bitmaps :(
Commenter la réponse de cs_MAURICIO
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
3 août 2018
0
Merci
pour une copie complète ceci devrait suffir :
aCanvas.Draw(x, y,  aBgPicture.Picture.Graphic);

 
@+
Cirec

<hr siz="" />
Commenter la réponse de Cirec
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
0
Merci
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+
Commenter la réponse de cs_MAURICIO
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
0
Merci
"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+
Commenter la réponse de cs_MAURICIO
Messages postés
4304
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
9 mars 2018
0
Merci
<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);

Commenter la réponse de f0xi

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.