C# 使用锁位更改alpha系数

C# 使用锁位更改alpha系数,c#,winforms,pixel,alpha,lockbits,C#,Winforms,Pixel,Alpha,Lockbits,我写了一个函数,可以改变图像的alpha系数。我使用setpixel和getpixel,速度非常慢。我发现Lockbits方法更快。如何使用Lockbits呢? 这是我目前的代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Imaging; using Syst

我写了一个函数,可以改变图像的alpha系数。我使用setpixel和getpixel,速度非常慢。我发现Lockbits方法更快。如何使用Lockbits呢? 这是我目前的代码:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        private static Image Tran(Image s,int alpha)
        {
            int x = 0, y = 0;
            Bitmap tImage = new Bitmap(s);
            for (x = 0; x < tImage.Width; x++)
            {
                for (y = 0; y < tImage.Height; y++)
                {

                    tImage.SetPixel(x, y, Color.FromArgb(alpha, tImage.GetPixel(x, y).R, tImage.GetPixel(x, y).G, tImage.GetPixel(x, y).B));
                }
            }
            return tImage;

        }
        public Form1()
        {
            InitializeComponent();
            trackBar1.TickStyle = TickStyle.Both;
            trackBar1.Orientation = Orientation.Vertical;
            trackBar1.Minimum = 0;
            trackBar1.Maximum = 255;
            trackBar1.Height = 101;
            trackBar1.Value = 255;
            pictureBox1.Image = Image.FromFile("C:\\Users\\rati\\Desktop\\water.jpg");
            pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
        }
        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            pictureBox1.Image = ChangeAlpha(pictureBox1.Image, trackBar1.Value);

            textBox1.Text = trackBar1.Value.ToString();

        }


    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用系统、绘图、成像;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows.Forms;
命名空间Windows窗体应用程序2
{
公共部分类Form1:Form
{
专用静态图像传输(图像s,int alpha)
{
int x=0,y=0;
位图时间=新位图;
对于(x=0;x
您可以通过使用新的位图将图像绘制在新位图中,并将介于0和1之间的浮点值指定给图像作为其新的alpha值来更改图像的不透明度:

public Image ChangeAlpha(Image img, int value)
{
    if (value < 0 || value > 255)
        throw new Exception("value must be between 0 and 255");

    Bitmap bmp = new Bitmap(img.Width, img.Height); // Determining Width and Height of Source Image
    Graphics graphics = Graphics.FromImage(bmp);
    ColorMatrix colormatrix = new ColorMatrix();
    colormatrix.Matrix33 = value / 255f;
    ImageAttributes imgAttribute = new ImageAttributes();
    imgAttribute.SetColorMatrix(colormatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
    graphics.DrawImage(img, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imgAttribute);
    graphics.Dispose();   // Releasing all resource used by graphics 
    return bmp;
}
不要忘记使用System.Drawing添加
使用System.Drawing.Imaging

您可以在调用
value=127的函数之前和之后看到以下内容:

编辑

如果要在
图片框中查看结果,应注意使用两个不同的图片框,一个用于原始图像,一个用于更改图像:

private void trackBar1_Scroll(object sender, EventArgs e)
{
    this.pictureBox2.Image = ChangeAlpha(this.pictureBox1.Image, this.trackBar1.Value);
}

正如我在代码中看到的,当您更改不透明度时,您再次将结果设置为
PictureBox1的图像,并再次对结果应用不透明度。换言之,您可以对之前多次应用不透明度的图像应用不透明度。

您可以通过使用新的位图在新位图中绘制图像,并将介于0和1之间的浮点值指定给图像作为其新的alpha值来更改图像的不透明度:

public Image ChangeAlpha(Image img, int value)
{
    if (value < 0 || value > 255)
        throw new Exception("value must be between 0 and 255");

    Bitmap bmp = new Bitmap(img.Width, img.Height); // Determining Width and Height of Source Image
    Graphics graphics = Graphics.FromImage(bmp);
    ColorMatrix colormatrix = new ColorMatrix();
    colormatrix.Matrix33 = value / 255f;
    ImageAttributes imgAttribute = new ImageAttributes();
    imgAttribute.SetColorMatrix(colormatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
    graphics.DrawImage(img, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imgAttribute);
    graphics.Dispose();   // Releasing all resource used by graphics 
    return bmp;
}
public Form1()
{
    ...
    originalImage = new Bitmap("C:\\Users\\rati\\Desktop\\water.jpg");
    pictureBox1.Image = originalImage;
    ...
}

// Add an extra field to the Form class.
Bitmap originalImage;

void trackBar1_Scroll(object sender, EventArgs e)
{
    pictureBox1.Image = ChangeAlpha((byte)trackBar1.Value);
    textBox1.Text = trackBar1.Value.ToString();
}

Image ChangeAlpha(byte alpha)
{
    Bitmap bmp = new Bitmap(originalImage);

    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);

    IntPtr ptr = bmpData.Scan0;

    int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
    byte[] rgbValues = new byte[bytes];

    Marshal.Copy(ptr, rgbValues, 0, bytes);

    // Set every fourth value to alpha. A 32bpp bitmap will change transparency.
    for (int counter = 3; counter < rgbValues.Length; counter += 4)
        rgbValues[counter] = alpha;

    // Also you can try parallelize loop.
    //int length = rgbValues.Length / 4;
    //Parallel.For(3, length, counter => rgbValues[counter * 4 - 1] = alpha);

    Marshal.Copy(rgbValues, 0, ptr, bytes);
    bmp.UnlockBits(bmpData);

    return bmp;
}
不要忘记使用System.Drawing添加
使用System.Drawing.Imaging

您可以在调用
value=127的函数之前和之后看到以下内容:

编辑

如果要在
图片框中查看结果,应注意使用两个不同的图片框,一个用于原始图像,一个用于更改图像:

private void trackBar1_Scroll(object sender, EventArgs e)
{
    this.pictureBox2.Image = ChangeAlpha(this.pictureBox1.Image, this.trackBar1.Value);
}
正如我在代码中看到的,当您更改不透明度时,您再次将结果设置为
PictureBox1的图像,并再次对结果应用不透明度。换句话说,你在一张图像上应用了不透明度,而之前你又一次地对它应用了不透明度。

public Form1()
public Form1()
{
    ...
    originalImage = new Bitmap("C:\\Users\\rati\\Desktop\\water.jpg");
    pictureBox1.Image = originalImage;
    ...
}

// Add an extra field to the Form class.
Bitmap originalImage;

void trackBar1_Scroll(object sender, EventArgs e)
{
    pictureBox1.Image = ChangeAlpha((byte)trackBar1.Value);
    textBox1.Text = trackBar1.Value.ToString();
}

Image ChangeAlpha(byte alpha)
{
    Bitmap bmp = new Bitmap(originalImage);

    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);

    IntPtr ptr = bmpData.Scan0;

    int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
    byte[] rgbValues = new byte[bytes];

    Marshal.Copy(ptr, rgbValues, 0, bytes);

    // Set every fourth value to alpha. A 32bpp bitmap will change transparency.
    for (int counter = 3; counter < rgbValues.Length; counter += 4)
        rgbValues[counter] = alpha;

    // Also you can try parallelize loop.
    //int length = rgbValues.Length / 4;
    //Parallel.For(3, length, counter => rgbValues[counter * 4 - 1] = alpha);

    Marshal.Copy(rgbValues, 0, ptr, bytes);
    bmp.UnlockBits(bmpData);

    return bmp;
}
{ ... originalImage=新位图(“C:\\Users\\rati\\Desktop\\water.jpg”); pictureBox1.图像=原始图像; ... } //向表单类添加一个额外字段。 位图原始图像; void trackBar1\u滚动(对象发送器、事件参数e) { pictureBox1.Image=changeapha((字节)trackBar1.Value); textBox1.Text=trackBar1.Value.ToString(); } 图像更改alpha(字节alpha) { 位图bmp=新位图(原始图像); 矩形rect=新矩形(0,0,bmp.Width,bmp.Height); BitmapData bmpData=bmp.LockBits(rect,ImageLockMode.ReadWrite,bmp.PixelFormat); IntPtr ptr=bmpData.Scan0; int bytes=Math.Abs(bmpData.Stride)*bmp.Height; 字节[]rgbValues=新字节[字节]; Marshal.Copy(ptr,rgbvalue,0,字节); //将每四分之一的值设置为alpha。32bpp位图将更改透明度。 对于(int计数器=3;计数器RGB值[计数器*4-1]=alpha); Marshal.Copy(rgbvalue,0,ptr,字节); bmp.UnlockBits(bmpData); 返回bmp; }
公共表单1()
{
...
originalImage=新位图(“C:\\Users\\rati\\Desktop\\water.jpg”);
pictureBox1.图像=原始图像;
...
}
//向表单类添加一个额外字段。
位图原始图像;
void trackBar1\u滚动(对象发送器、事件参数e)
{
pictureBox1.Image=changeapha((字节)trackBar1.Value);
textBox1.Text=trackBar1.Value.ToString();
}
图像更改alpha(字节alpha)
{
位图bmp=新位图(原始图像);
矩形rect=新矩形(0,0,bmp.Width,bmp.Height);
BitmapData bmpData=bmp.LockBits(rect,ImageLockMode.ReadWrite,bmp.PixelFormat);
IntPtr ptr=bmpData.Scan0;
int bytes=Math.Abs(bmpData.Stride)*bmp.Height;
字节[]rgbValues=新字节[字节];
Marshal.Copy(ptr,rgbvalue,0,字节);
//将每四分之一的值设置为alpha。32bpp位图将更改透明度。
对于(int计数器=3;计数器RGB值[计数器*4-1]=alpha);
Marshal.Copy(rgbvalue,0,ptr,字节);
bmp.UnlockBits(bmpData);
返回bmp;
}
中的第一个例程可能是一个锁位示例