2011-01-24 41 views
17

Tengo un formulario que tiene una imagen. Estoy usando un control deslizante para cambiar la opacidad de la imagen. Entonces, en el evento "ValueChanged" del control deslizante estoy llamando al siguiente método para cambiar la opacidad.Cambiar la opacidad de una imagen de mapa de bits

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

La imagen devuelta se establece en la imagen original.

Mi problema es que la opacidad de la imagen no está cambiando ... Si hay algún error, por favor sea tan amable de señalar .. Thnx ...

Respuesta

35

prueba este de CodeProject - Change Opacity of Image in 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; 
    } 
} 
+0

Su comentario para el parámetro opacity dice "porcentaje de opacidad", pero no es un porcentaje, es un factor absoluto, es decir, en el rango de 0.0 a 1.0. – RenniePet

+0

Me tomó algunas horas de excavación, pero esta fue la publicación que finalmente respondió por mí. ¡Gracias! – samuelesque

+5

Matemáticamente no hay diferencia entre 65% y 0.65. Ellos son equivalentes. –

2

No estoy familiarizado con el enfoque ImageAttributes, pero debería poder simplemente recorrer todos los píxeles de la imagen y modificar el componente alfa del color del píxel.

+1

Tengo algo que aclarar. Si voy a recorrer todos los píxeles, entonces consumirá tiempo. ¿Alguna manera directa? Thnx para pronta respuesta – JCTLK

+1

@JCTLK: Por supuesto que sí. Se puede hacer bastante rápido en imágenes pequeñas. – leppie

14

bucle que sobre los píxeles y juega sólo el canal alfa. Si haces esto con Bitmap.LockBits, en realidad será muy rápido.

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; 
    } 
+2

Este debería ser el mejor ¡responder! – buzznfrog

+0

Odio ser un aguafiestas, pero devolvería nulo si la imagen no se puede modificar en caso de que se deshaga del resultado más adelante. Pero gran ayuda Jan. Gracias :) – Czeshirecat

-1

El método ImageAttributes no tendrán ningún problema con PNG como el post original que ha enumerado, pero para JPEG es necesario inundar llenar el lienzo con un color gráficos primero. Dado que esto puede dejar un pequeño borde no deseado, solo hágalo si la opacidad es algo inferior a 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 
// ... 
Cuestiones relacionadas