使用ColorMatrix进行颜色变换
作者:Leven 日期:2008-05-17 22:03:58
今天准备做个水印图片系统,使用ColorMatrix对图片进行颜色处理.发现这个东西的使用比较麻烦,现将此总结下.
首先要明白,在GDI+中,Color的表示方式为ARGB的方式,也就是一个颜色对象有Alpha,Red,Green,Blue四个分量.
如果我们要改变整个图片的颜色怎么办呢?第一种方法就是对图片每个点的颜色进行转换,比如我想让图片的红色加重一点,那么我需要遍历全部像素,然后对每个像素的的颜色值进行计算.这个方法思路清晰简单,不过效率就实在不敢恭维了,因此,.GDI+中使用颜色变换都是基于ColorMatrix的,这儿的颜色表示和上面有点区别,上面使用(a,r,g,b)中,a,r,g,b的范围是0-255,但是在这儿a,r,g,b的范围是0-1,它使用一个5x5矩阵来表示颜色变换,为什么要使用5x5矩阵而不是4x4矩阵呢?官方的解释是:"可通过用 4×4 矩阵乘以这些颜色矢量将线性变换(旋转和缩放等)应用到颜色矢量中。但是,您不能使用 4×4 矩阵进行平移(非线性)。如果在每个颜色矢量中再添加一个虚拟的第 5 坐标(例如,数字 1),则可使用 5×5 矩阵应用任何组合形式的线性变换和平移。由线性变换组成的后跟平移的变换称为仿射变换。"
那么,具体来说应如何变换呢?比如,我要将图片中每个像素的R值修改为255,那么我们可以使用的计算方法为"r*0 + 1",则对应矩阵为:
[0,0,0,0,0]
[0,1,0,0,0]
[0,0,1,0,0]
[0,0,0,1,0]
[1,0,0,0,1]
比如有一个点为[0.3,0.2,0.4,1]转换计算为:
[0,0,0,0,0]
[0,1,0.0,0]
[0.3,0.2,0.4,1,1] * [0,0,1,0,0] = [1,0.2,0.4,1,1]
[0,0,0,1,0]
[1,0,0,0,1]
很显然得到了预期结果
那么我们再来看看我们这次需要的,对图片透明的修改,很显然是修改alpha值,比如有float alpha,则变换如下:
[1,0,0,0,0]
[0,1,0,0,0]
[0,0,1,0,0]
[0,0,0,alpha /(float)255,0]
[0,0,0,0,0]
则能完成变换.
最后贴上水印图片生成类代码:
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.IO;
- using System.Drawing;
- using System.Drawing.Imaging;
- namespace LImage.Library
- {
- public class ImageWater : IWater
- {
- private string imagePath;
- private Image waterImage;
- public override TreatmentType Type
- {
- get { return TreatmentType.ImageWater; }
- }
- public string ImagePath
- {
- get { return imagePath; }
- set { imagePath = value; }
- }
- public ImageWater()
- {
- imagePath = string.Empty;
- waterPoint = WaterPoint.Create(0, 0);
- waterImage = null;
- waterColor = Color.FromArgb(128, 255, 255, 255);
- }
- public ImageWater(string path)
- : this()
- {
- imagePath = path;
- }
- public ImageWater(string path, WaterPoint point)
- :this()
- {
- imagePath = path;
- waterPoint = point;
- }
- public ImageWater(string imagePath, WaterPoint point, Color color)
- : this()
- {
- waterPoint = point;
- waterColor = color;
- }
- public void LoadWaterImage()
- {
- if (!File.Exists(imagePath))
- throw new Exception("找不到水印图片.");
- waterImage = null;
- try
- {
- waterImage = Image.FromFile(imagePath);
- }
- catch
- {
- throw new Exception("无法识别的图片格式.");
- }
- }
- public override void Treatment(string path)
- {
- if (waterImage == null)
- LoadWaterImage();
- if (!File.Exists(path))
- throw new Exception(string.Format("图片{0}不存在或者已经被删除.", path));
- Image image = null;
- FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
- try
- {
- image = Image.FromStream(fs);
- }
- catch
- {
- throw new Exception("不可识别的图片格式.");
- }
- finally
- {
- fs.Close();
- }
- Graphics imageG = Graphics.FromImage(image);
- SolidBrush brush = new SolidBrush(waterColor);
- float px, py;
- switch (waterPoint.Type)
- {
- case WaterPoint.PointType.LeftTop:
- default:
- px = waterPoint.x;
- py = waterPoint.y;
- break;
- case WaterPoint.PointType.LeftBottom:
- px = waterPoint.x;
- py = image.Height - waterPoint.y - waterImage.Height;
- break;
- case WaterPoint.PointType.RightTop:
- px = image.Width - waterPoint.x - waterImage.Width;
- py = waterPoint.y;
- break;
- case WaterPoint.PointType.RightBottom:
- px = image.Width - waterPoint.x - waterImage.Width;
- py = image.Height - waterPoint.y - waterImage.Height;
- break;
- }
- if (px < 0)
- px = 0;
- if (py < 0)
- py = 0;
- addWatermarkImage(imageG, (int)px, (int)py);
- imageG.Save();
- fs = new FileStream(path, FileMode.Create, FileAccess.Write);
- Bitmap bitmap = new Bitmap(image);
- bitmap.Save(fs, image.RawFormat);
- //image.Save(fs, ImageFormat.Jpeg);
- fs.Close();
- }
- private void addWatermarkImage(Graphics picture, int px, int py)
- {
- ImageAttributes imageAttributes = new ImageAttributes();
- ColorMap colorMap = new ColorMap();
- float af = waterColor.A / (float)255;
- ColorMap[] remapTable = { colorMap };
- imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
- float[][] colorMatrixElements = {
- new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
- new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
- new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
- new float[] {0.0f, 0.0f, 0.0f, af, 0.0f},
- new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
- };
- ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);
- imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
- picture.DrawImage(waterImage, new Rectangle(px, py, waterImage.Width, waterImage.Height), 0, 0, waterImage.Width, waterImage.Height, GraphicsUnit.Pixel, imageAttributes);
- imageAttributes.Dispose();
- }
- }
- }
上一篇
下一篇
文章来自:
Tags: