web-dev-qa-db-ja.com

ビットマップ画像の不透明度を変更する

画像のあるフォームを持っています。スライダーを使用して画像の不透明度を変更しています。スライダーの「ValueChanged」イベントで、次のメソッドを呼び出して不透明度を変更します。

//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;  
}

返された画像は元の画像に設定されます。

私の問題は、画像の不透明度が変わらないことです...エラーがある場合は指摘してください.. Thnx ...

22
JCTLK

CodeProjectからこれを試してください- 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

ピクセルをループして、アルファチャネルのみを再生します。これをBitmap.LockBitsで行うと、実際には非常に高速になります。

    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

私はImageAttributesアプローチに精通していませんが、画像のすべてのピクセルを単純に実行し、ピクセルの色のアルファコンポーネントを変更できるはずです。

2
leppie

ImageAttributesメソッドは、元の投稿にリストされているため、PNGで正常に機能しますが、JPEGの場合は、最初にグラフィックキャンバスを色で塗りつぶす必要があります。これは小さな望ましくない境界線を残す可能性があるため、不透明度が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