C# GDI+颜色融合

1、使用BitBlt进行背景融合,参考:http://www.pinvoke.net/default.aspx/Enums/TernaryRasterOperations.html

http://www.pinvoke.net/default.aspx/gdi32/StretchBlt.html

https://www.cnblogs.com/zhaogaojian/p/8365241.html

public static extern bool BitBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, [In] IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

[DllImport("gdi32.dll")]
public static extern bool StretchBlt(IntPtr hdcDest, int nXOriginDest,
	int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hdcSrc,
	int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
	TernaryRasterOperations dwRop);

[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern bool DeleteDC(IntPtr hdc);

[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);

[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern bool DeleteObject(IntPtr hObject);

[DllImport("gdi32.dll")]
public static extern bool SetStretchBltMode(IntPtr hdc, StretchMode iStretchMode);

public enum StretchMode
{
	STRETCH_ANDSCANS = 1,
	STRETCH_ORSCANS = 2,
	STRETCH_DELETESCANS = 3,
	STRETCH_HALFTONE = 4,
}

public enum TernaryRasterOperations
{
	SRCCOPY = 0x00CC0020, /* dest = source*/
	SRCPAINT = 0x00EE0086, /* dest = source OR dest*/
	SRCAND = 0x008800C6, /* dest = source AND dest*/
	SRCINVERT = 0x00660046, /* dest = source XOR dest*/
	SRCERASE = 0x00440328, /* dest = source AND (NOT dest )*/
	NOTSRCCOPY = 0x00330008, /* dest = (NOT source)*/
	NOTSRCERASE = 0x001100A6, /* dest = (NOT src) AND (NOT dest) */
	MERGECOPY = 0x00C000CA, /* dest = (source AND pattern)*/
	MERGEPAINT = 0x00BB0226, /* dest = (NOT source) OR dest*/
	PATCOPY = 0x00F00021, /* dest = pattern*/
	PATPAINT = 0x00FB0A09, /* dest = DPSnoo*/
	PATINVERT = 0x005A0049, /* dest = pattern XOR dest*/
	DSTINVERT = 0x00550009, /* dest = (NOT dest)*/
	BLACKNESS = 0x00000042, /* dest = BLACK*/
	WHITENESS = 0x00FF0062, /* dest = WHITE*/
};
public static void ConvertImageByBitBlt(string src, string dest)
{
	Bitmap srcImage = new Bitmap(src);
	Bitmap destImage = new Bitmap(srcImage.Width, srcImage.Height);
	try
	{
		using (var g = Graphics.FromImage(destImage))
		{
			//g.SmoothingMode = SmoothingMode.HighQuality;  //图片柔顺模式选择
			//g.InterpolationMode = InterpolationMode.HighQualityBicubic;//高质量
			//g.CompositingQuality = CompositingQuality.HighQuality;//再加一点

			Brush b = new SolidBrush(Color.FromArgb(199, 237, 204));
			g.FillRectangle(b, new Rectangle(0, 0, destImage.Width, destImage.Height));
			g.Flush();

			IntPtr pTarget = g.GetHdc();
			IntPtr pSource = Win32.CreateCompatibleDC(pTarget);
			IntPtr hbmp = srcImage.GetHbitmap();
			IntPtr pOrig = Win32.SelectObject(pSource, hbmp);

			//Win32.StretchBlt(pTarget, 0, 0, destImage.Width, destImage.Height, pSource,
			//    0, 0, srcImage.Width, srcImage.Height, TernaryRasterOperations.WHITENESS);

			Win32.BitBlt(pTarget, 0, 0, destImage.Width, destImage.Height, pSource, 0, 0, TernaryRasterOperations.SRCAND);

			IntPtr pNew = Win32.SelectObject(pSource, pOrig);
			Win32.DeleteObject(hbmp);
			Win32.DeleteDC(pSource);

			// g未释放, 此时保存,只会有背景,而没有图片
			//destImage.Save(dest);
		}
		destImage.Save(dest);
	}
	catch (Exception ex)
	{
		Console.WriteLine(ex.ToString());
	}
	finally
	{
		srcImage.Dispose();
		destImage.Dispose();
	}
}

2、使用TextureBrush

public static void ConvertImageByGDIPlus(string src, string dest)
{
	Bitmap srcImage = new Bitmap(src);
	Bitmap destImage = new Bitmap(srcImage.Width, srcImage.Height);
	try
	{
		using (var g = Graphics.FromImage(destImage))
		{
			//颜色矩阵
			float[][] matrixItems =
			{
				  new float[]{(float)199 / 255f,0,0,0,0},
				  new float[]{0,(float)237 / 255f,0,0,0},
				  new float[]{0,0,(float)204 / 255f,0,0},
				  new float[]{0,0,0,(float)100 / 100,0},
				  new float[]{0,0,0,0,1f}
			 };
			ColorMatrix colorMatrix = new ColorMatrix(matrixItems);
			ImageAttributes imageAtt = new ImageAttributes();
			imageAtt.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

			TextureBrush tb = new TextureBrush(srcImage, new Rectangle(0, 0, srcImage.Width, srcImage.Height), imageAtt);
			g.FillRectangle(tb, new Rectangle(0, 0, destImage.Width, destImage.Height));
			g.Flush();
		}
		destImage.Save(dest);
	}
	catch (Exception ex)
	{
		Console.WriteLine(ex.ToString());
	}
	finally
	{
		srcImage.Dispose();
		destImage.Dispose();
	}
}

3、使用ColorMatrix ,参考:

https://docs.microsoft.com/zh-cn/dotnet/desktop/winforms/advanced/how-to-use-a-color-matrix-to-transform-a-single-color?view=netframeworkdesktop-4.8

public static void ConvertImageByColorMatrix(string src, string dest)
{
	Bitmap srcImage = new Bitmap(src);
	Bitmap destImage = new Bitmap(srcImage.Width, srcImage.Height);
	try
	{
		using (var g = Graphics.FromImage(destImage))
		{
			//颜色矩阵
			float[][] matrixItems =
			{
				  new float[]{(float)199 / 255f,0,0,0,0},
				  new float[]{0,(float)237 / 255f,0,0,0},
				  new float[]{0,0,(float)204 / 255f,0,0},
				  new float[]{0,0,0,(float)100 / 100,0},
				  new float[]{0,0,0,0,1f}
			 };
			ColorMatrix colorMatrix = new ColorMatrix(matrixItems);
			ImageAttributes imageAtt = new ImageAttributes();
			imageAtt.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
			g.DrawImage(srcImage, new Rectangle(0, 0, destImage.Width, destImage.Height),
				0, 0, srcImage.Width, srcImage.Height, GraphicsUnit.Pixel, imageAtt);
			g.Flush();
		}

		destImage.Save(dest, srcImage.RawFormat);
	}
	catch (Exception ex)
	{
		Console.WriteLine(ex.ToString());
	}
	finally
	{
		srcImage.Dispose();
		destImage.Dispose();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值