2011-01-24 7 views
17

Ho un modulo con un'immagine. Sto usando un cursore per cambiare l'opacità dell'immagine. Quindi nell'evento "ValueChanged" del cursore sto chiamando il seguente metodo per cambiare l'opacità.Modifica dell'opacità di un'immagine bitmap

//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'immagine restituita è impostata sull'immagine originale.

mio problema è che l'opacità dell'immagine non cambia ... Se c'è qualche errore si prega di essere così gentile da sottolineare .. Thnx ...

risposta

35

provare questo da 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

Il commento per l'opacità del parametro indica "percentuale di opacità", ma non è una percentuale, è un fattore assoluto, vale a dire nell'intervallo da 0.0 a 1.0. – RenniePet

+0

Mi ci sono volute alcune ore di scavo, ma questo era il post che alla fine mi ha risposto. Grazie! – samuelesque

+5

Matematicamente non vi è alcuna differenza tra il 65% e lo 0,65. Sono equivalenti. –

2

non ho familiarità con l'approccio ImageAttributes, ma dovresti essere in grado di scorrere semplicemente tutti i pixel dell'immagine e modificare il componente alfa del colore del pixel.

+1

Ho qualcosa da chiarire. Se devo attraversare tutti i pixel, allora consumerà tempo. Qualunque via diretta? Thnx per pronta risposta – JCTLK

+1

@JCTLK: Certo che lo sarà. Può essere fatto abbastanza velocemente su piccole immagini. – leppie

14

si esegue un ciclo sui pixel e giocare solo il canale alfa. Se lo fai con Bitmap.LockBits sarà davvero molto veloce.

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

Questo dovrebbe essere il migliore risposta! – buzznfrog

+0

L'odio è un killjoy, ma restituirei null se l'immagine non può essere modificata in caso di eliminazione del risultato in un secondo momento. Ma grande aiuto Jan. Grazie :) – Czeshirecat

-1

Il metodo ImageAttributes funzionerà benissimo con PNG come il post originale è esso elencati, ma per JPEG è necessario Riempi la tela grafica con un colore prima. Poiché questo può lasciare un piccolo bordo indesiderato, farlo solo se l'opacità è qualcosa di meno di 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 
// ...