如果能根据剩下的不透明的截图,把多余的透明去掉
这里我理解的是把源图一部分没图像的去掉?
我写了三个方法,你参考一下,还有各个方法执行所消耗的时间(Stopwatch)//托管
public Bitmap ToTransparentPng1(Bitmap source, Rectangle dest, Color transparentColor)
{
    if (source == null) return null;
    Rectangle src = new Rectangle(0, 0, source.Width, source.Height);
    src.Intersect(dest);
    if (src != dest)
    {
        throw new ArgumentOutOfRangeException();
    }
    Bitmap newBitmap = new Bitmap(dest.Width, dest.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    for (int y = dest.Y; y < dest.Bottom; y++)
    {
        for (int x = dest.X; x < dest.Right; x++) 
        {
            Color srcColor = source.GetPixel(x,y);
            if (srcColor != transparentColor)
            {
                newBitmap.SetPixel(x - dest.X, y-dest.Y, srcColor);
            }
        }
    }
    return newBitmap;
}//指针
public Bitmap ToTransparentPng2(Bitmap source, Rectangle dest, Color transparentColor)
{
    if (source == null) return null;
    Rectangle src = new Rectangle(0,0,source.Width,source.Height);
    src.Intersect(dest);
    if (src != dest)
    {
        throw new ArgumentOutOfRangeException();
    }
    Bitmap newBitmap=new Bitmap(dest.Width,dest.Height,System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height),ImageLockMode.ReadOnly,source.PixelFormat);
    BitmapData destData = newBitmap.LockBits(new Rectangle(0,0,newBitmap.Width,newBitmap.Height),ImageLockMode.ReadWrite,newBitmap.PixelFormat);
    unsafe
    {
        for (int x = dest.X; x < dest.Right; x++)
        {
            for (int y = dest.Y; y < dest.Bottom; y++)
            {
                byte* pS = (byte*)sourceData.Scan0 + x * 4 + y*sourceData.Stride;
                byte* pD = (byte*)destData.Scan0 + (x - dest.X) * 4 + (y-dest.Y)*destData.Stride;
                byte B = *(pS + 0);
                byte G = *(pS + 1);
                byte R = *(pS + 2);
                byte A = *(pS + 3);
                if (Color.FromArgb(A, R, G, B) != transparentColor)
                {
                    *(pD + 0) = B;
                    *(pD + 1) = G;
                    *(pD + 2) = R;
                    *(pD + 3) = 255;
                }
            }
        }
        newBitmap.UnlockBits(destData);
        source.UnlockBits(sourceData);
    }
    return newBitmap;
}//非托管
public Bitmap ToTransparentPng3(Bitmap source, Rectangle dest, Color transparentColor)
{
    if (source == null) return null;
    Rectangle src = new Rectangle(0, 0, source.Width, source.Height);
    src.Intersect(dest);
    if (src != dest)
    {
        throw new ArgumentOutOfRangeException();
    }
    BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, source.PixelFormat);
    byte[] buffer = new byte[source.Width * sourceData.Stride];
    Marshal.Copy(sourceData.Scan0, buffer, 0, buffer.Length);
    Bitmap newBitmap = new Bitmap(dest.Width, dest.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    BitmapData destData = newBitmap.LockBits(new Rectangle(0, 0, newBitmap.Width, newBitmap.Height), ImageLockMode.ReadOnly, newBitmap.PixelFormat);
    byte[] newBuffer = new byte[newBitmap.Width * destData.Stride];
    for (int i = 0; i < newBuffer.Length; i += 4)
    {
        byte B = buffer[i + dest.X + 0];
        byte G = buffer[i + dest.X + 1];
        byte R = buffer[i + dest.X + 2];
        byte A = buffer[i + dest.X + 3];
        if (Color.FromArgb(A, R, G, B) != transparentColor)
        {
            newBuffer[i + 0] = B;
            newBuffer[i + 1] = G;
            newBuffer[i + 2] = R;
            newBuffer[i + 3] = 255;
        }
    }
    Marshal.Copy(newBuffer,0,destData.Scan0,newBuffer.Length);
    newBitmap.UnlockBits(destData);
    source.UnlockBits(sourceData);
    return newBitmap;
}
Bitmap ToTransparentPngX(Bitmap source, Rectangle dest, Color transparentColor)
其中参数信息:
source:源图
dest:想要透明化的目标区域
transparentColor:颜色键

解决方案 »

  1.   

    再加一种方法public Bitmap ToTransparentPng4(Bitmap source, Rectangle dest, Color transparentColor)
    {
        if (source == null) return null;
        Rectangle src = new Rectangle(0, 0, source.Width, source.Height);
        src.Intersect(dest);
        if (src != dest)
        {
            throw new ArgumentOutOfRangeException();
        }
        Bitmap newBitmap = new Bitmap(dest.Width, dest.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        source.MakeTransparent(transparentColor);
        Graphics g = Graphics.FromImage(newBitmap);
        g.DrawImage(source, new Rectangle(0, 0, dest.Width, dest.Height), dest, GraphicsUnit.Pixel);
        g.Dispose();
        return newBitmap;
    }
      

  2.   

    方法4第10行到14行换成下面的代码就避免源图被修改,用一张临时位图做透明化Bitmap temp = (Bitmap)source.Clone();
    temp.MakeTransparent(transparentColor);
    Bitmap newBitmap = new Bitmap(dest.Width, dest.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);     
    Graphics g = Graphics.FromImage(newBitmap);
    g.DrawImage(temp, new Rectangle(0, 0, dest.Width, dest.Height), dest, GraphicsUnit.Pixel);
    g.Dispose();
    temp.Dispose();
      

  3.   

    PNG图片要做透明背景还是什么?
      

  4.   

    我上面写的方法三错了(如果想返回源图某区域像素对应不上),这里修改下public Bitmap ToTransparentPng3(Bitmap source, Rectangle dest, Color transparentColor)
    {
        if (source == null) return null;
        Rectangle src = new Rectangle(0, 0, source.Width, source.Height);
        src.Intersect(dest);
        if (src != dest)
        {
            throw new ArgumentOutOfRangeException();
        }
        BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, source.PixelFormat);
        byte[] buffer = new byte[source.Height * sourceData.Stride];
        Marshal.Copy(sourceData.Scan0, buffer, 0, buffer.Length);
        Bitmap newBitmap = new Bitmap(dest.Width, dest.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        BitmapData destData = newBitmap.LockBits(new Rectangle(0, 0, newBitmap.Width, newBitmap.Height), ImageLockMode.ReadOnly, newBitmap.PixelFormat);
        byte[] newBuffer = new byte[newBitmap.Height * destData.Stride];    int targetId = (dest.X + dest.Y * source.Width) * 4;
        for (int i = 0; i < newBuffer.Length; i += 4)
        {
            int offset = targetId + i + (sourceData.Stride - destData.Stride) * (i / destData.Stride);
            byte B = buffer[offset + 0];
            byte G = buffer[offset + 1];
            byte R = buffer[offset + 2];
            byte A = buffer[offset + 3];
            if (Color.FromArgb(A, R, G, B) != transparentColor)
            {
                newBuffer[i + 0] = B;
                newBuffer[i + 1] = G;
                newBuffer[i + 2] = R;
                newBuffer[i + 3] = 255;
            }
        }
        Marshal.Copy(newBuffer, 0, destData.Scan0, newBuffer.Length);
        newBitmap.UnlockBits(destData);
        source.UnlockBits(sourceData);
        return newBitmap;
    }
      

  5.   

    不知道要的是不是这种效果,参考下//将Image类型的图片转换为Bitmap
    Bitmap bitmap = new Bitmap(this.SkinBack);
    //判断要透明的颜色不等于透明,否则不处理,免得浪费资源
    if (SkinTrankColor != Color.Transparent)
    {
        //MakeTransparent函数透明指定颜色
        bitmap.MakeTransparent(SkinTrankColor);
    }
    //End完毕