web-dev-qa-db-fra.com

Modification de l'opacité d'une image bitmap

J'ai un formulaire qui a une image. J'utilise un curseur pour changer l'opacité de l'image. Donc, dans l'événement "ValueChanged" du curseur, j'appelle la méthode suivante pour changer l'opacité.

//Setting the opacity of the image
public static Image SetImgOpacity(Image imgPic, float imgOpac)
{   
     Bitmap bmpPic = new Bitmap(imgPic.Width, imgPic.Height);
     Graphics gfxPic = Graphics.FromImage(bmpPic);

     ColorMatrix cmxPic = new ColorMatrix();   
     cmxPic.Matrix33 = imgOpac;   
     ImageAttributes iaPic = new ImageAttributes();   
     iaPic.SetColorMatrix(cmxPic, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);  
     gfxPic.DrawImage(imgPic, new Rectangle(0, 0, bmpPic.Width, bmpPic.Height), 0, 0, imgPic.Width, imgPic.Height, GraphicsUnit.Pixel, iaPic);  
     gfxPic.Dispose();            

     return bmpPic;  
}

L'image retournée est définie sur l'image d'origine.

Mon problème est que l'opacité de l'image ne change pas ... S'il y a une erreur veuillez être gentil de le signaler .. Thnx ...

22
JCTLK

Essayez celui-ci à partir de CodeProject - Changer l'opacité de l'image en C # :

/// <summary>  
/// method for changing the opacity of an image  
/// </summary>  
/// <param name="image">image to set opacity on</param>  
/// <param name="opacity">percentage of opacity</param>  
/// <returns></returns>  
public Image SetImageOpacity(Image image, float opacity)  
{  
    try  
    {  
        //create a Bitmap the size of the image provided  
        Bitmap bmp = new Bitmap(image.Width, image.Height);  

        //create a graphics object from the image  
        using (Graphics gfx = Graphics.FromImage(bmp)) {  

            //create a color matrix object  
            ColorMatrix matrix = new ColorMatrix();      

            //set the opacity  
            matrix.Matrix33 = opacity;  

            //create image attributes  
            ImageAttributes attributes = new ImageAttributes();      

            //set the color(opacity) of the image  
            attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);    

            //now draw the image  
            gfx.DrawImage(image, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
        }
        return bmp;  
    }  
    catch (Exception ex)  
    { 
        MessageBox.Show(ex.Message);  
        return null;  
    }  
} 
46
Venkatesh Appala

Vous bouclez sur les pixels et jouez uniquement le canal alpha. Si vous faites cela avec Bitmap.LockBits, cela sera en fait très rapide.

    private const int bytesPerPixel = 4;

    /// <summary>
    /// Change the opacity of an image
    /// </summary>
    /// <param name="originalImage">The original image</param>
    /// <param name="opacity">Opacity, where 1.0 is no opacity, 0.0 is full transparency</param>
    /// <returns>The changed image</returns>
    public static Image ChangeImageOpacity(Image originalImage, double opacity)
    {
        if ((originalImage.PixelFormat & PixelFormat.Indexed) == PixelFormat.Indexed)
        {
            // Cannot modify an image with indexed colors
            return originalImage;
        }

        Bitmap bmp = (Bitmap)originalImage.Clone();

        // Specify a pixel format.
        PixelFormat pxf = PixelFormat.Format32bppArgb;

        // Lock the bitmap's bits.
        Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
        BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf);

        // Get the address of the first line.
        IntPtr ptr = bmpData.Scan0;

        // Declare an array to hold the bytes of the bitmap.
        // This code is specific to a bitmap with 32 bits per pixels 
        // (32 bits = 4 bytes, 3 for RGB and 1 byte for alpha).
        int numBytes = bmp.Width * bmp.Height * bytesPerPixel;
        byte[] argbValues = new byte[numBytes];

        // Copy the ARGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(ptr, argbValues, 0, numBytes);

        // Manipulate the bitmap, such as changing the
        // RGB values for all pixels in the the bitmap.
        for (int counter = 0; counter < argbValues.Length; counter += bytesPerPixel)
        {
            // argbValues is in format BGRA (Blue, Green, Red, Alpha)

            // If 100% transparent, skip pixel
            if (argbValues[counter + bytesPerPixel - 1] == 0)
                continue;

            int pos = 0;
            pos++; // B value
            pos++; // G value
            pos++; // R value

            argbValues[counter + pos] = (byte) (argbValues[counter + pos] * opacity);
        }

        // Copy the ARGB values back to the bitmap
        System.Runtime.InteropServices.Marshal.Copy(argbValues, 0, ptr, numBytes);

        // Unlock the bits.
        bmp.UnlockBits(bmpData);

        return bmp;
    }
16
Jan Romell

Je ne connais pas l'approche ImageAttributes, mais vous devriez pouvoir simplement parcourir tous les pixels de l'image et modifier la composante alpha de la couleur du pixel.

2
leppie

La méthode ImageAttributes fonctionnera correctement avec PNG car la publication d'origine l'a répertoriée, mais pour JPEG, vous devez d'abord remplir le canevas graphique avec une couleur. Comme cela peut laisser une petite bordure indésirable, ne le faites que si l'opacité est inférieure à 1,0:

if(opacity < 1.0)
{
    // g is a Graphics object
    g.Clear(Color.White);
}
// set color matrix and draw image as shown in other posts
// ...
0
Bruce Pierson