我有一个带有图像的表格。我正在使用滑块来更改图像的不透明度。因此,在滑块的“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...
尝试 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;
}
}
您循环像素并仅播放 Alpha 通道。 如果您使用 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;
}
我不熟悉
ImageAttributes
方法,但您应该能够简单地遍历图像的所有像素并修改像素颜色的 alpha 分量。
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
// ...
如果您遵循其他答案,您会发现图像几乎看起来是倒置的,这可能不是您想要的。我挣扎了一段时间,直到我找到了这个答案 Alpha 通道无法按预期使用 WriteableBitmap by davecove。 本质上,对于每 4 个字节,您必须将每个字节除以它们的相对 alpha 值,然后使用新的 alpha 值相乘。
我的代码:
for (int i = 0; i < Values.Length; i += 4)
{
var currentA = Values[i + 3];
if (currentA > 0)
{
var newA = (byte)(255 * percent);
for (int j = 1; j < 3; j++)
{
Values[i + j] = (byte)Math.Round(Values[i + j] / (float)currentA * newA).Limit(0, 255);
}
}
}
其中 Values 是 argbValues,如 Jan Romell 的答案所示。
所以完整的解决方案如下所示:
public static void SetOpacity(Bitmap bmp, float percent)
{
var data = bmp.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.ReadWrite, bmp.PixelFormat);
int imgBytes = Math.Abs(data.Stride) * bmp.Height;
var imgValues = new byte[imgBytes];
Marshal.Copy(data.Scan0, imgValues, 0, imgValues.Length);
for (int i = 0; i < imgValues.Length; i += 4)
{
var currentA = imgValues[i + 3];
if (currentA > 0)
{
var newA = (byte)(255 * percent);
for (int j = 1; j < 3; j++)
{
imgValues[i + j] = (byte)Math.Round(imgValues[i + j] / (float)currentA * newA).Limit(0, 255);
}
}
}
Marshal.Copy(imgValues, 0, data.Scan0, imgValues.Length);
bmp.UnlockBits(data);
}