您的位置:首页 > 其它

读书笔记_GDI+程序设计_第五章(图像)(下)

2008-09-07 12:50 316 查看
5. 处理图像
通过设定目标矩形的大小,可以修剪图像。最终被修剪的图像的大小一般要比原图像小,而与用于定义修剪区域的那个矩形大小相同。
通过把一个三点数组作为一个参数传给DrawImage方法,可以对图像进行缩放、变形、水平或垂直的翻转,以及旋转操作。
第一点指定源位图的左上角点的目标位置
第二电指定源位图的右上角点的目标位置
第三点指定源位图的左下角点的目标位置

在旋转图像时,其结果类似于使用Bitmap.RotateFlip方法时得到的结果。但是有一个重要的区别要注意。这里,如果使用DrawImage方法来处理图像,就已经把它绘制到绘图表面上了,这样不会影响存储在内存中的图像。而Bitmap.RotateFlip方法是处理存储在内存中的图像。
使用Clone方法,可以生成指定源图像的一部分的拷贝。
Image的GetThumbnailImage方法可以得到图像的缩略图。如果图像源包含缩略图数据,这个方法就得到该数据。否则,这个方法会缩小图像,以创建一个缩略图图像。

6. 创建和绘制图像
使用Bitmap类的构造函数,我们可以得到一个新的Bitmap对象,它表示内存中的一个位图。
创建好Bitmap对象后,就可以获得一个Graphics类的一个实例,来封装位图的绘图表面。使用这个Graphics对象,就可以在位图中绘图。接着在Paint事件中,可以使用表示屏幕绘图表面的Graphics对象,把图像绘制到屏幕上。
绘制到Bitmap对象上的优点
性能——可以提前绘制图像,在需要它时在Paint事件中绘制图像。这样,就只需绘制一次图形,而不是在每次接收到Paint事件时都绘制它们。如果绘图过程比较费时,这样做肯定会提高性能。
动态生成图像——有时需要在网页中包含一个动态生成的图形。为此,可以在Web服务器上绘制图像,然后在网页上包含一个对该动态生成图像的引用。
准备复杂的3D图形——如果图形有多个层,即首先需要绘制背景,然后绘制中间图像、前景,在屏幕之外绘制图像就允许先完全准备好图像,再把它们显示到屏幕上,这将防止因在屏幕上绘制多层图像而导致的难看的效果。
而且,一些图像处理效果例如模糊和锐化,只能在显示图像之前通过直接处理图像来获得。提前绘制图像,就可以使用这些处理功能。

双倍缓存
Windows Forms和GDI+都无缝的支持双倍缓存。我们可以设置三个标志,然后GDI+就会考虑双倍缓存的所有细节。为了激活双倍缓存功能,需要使用Form类的SetStyle方法。把下面的代码放在窗体的构造函数或者Load事件中,就可以激活双倍缓存功能:
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
在控件绘制其整个界面时,把AllPaintingWmPaint和UserPaint设置为true;架构不会绘制控件的任何一部分,包括控件的背景。
这就是设置这些样式时发生的情况。在GDI+引发Paint事件时,不会把绘图表面设置为窗口,而是在内存中创建一个图像和一个Graphics对象,允许把该图像用作绘图表面。然后把Graphics对象作为参数的一部分传送给Paint事件。
这些都是在后台进行的。绘图代码不需要知道它应在图像上绘图,而不是直接绘制到屏幕上。在Paint事件返回后,构架就会把准备好的图像绘制到窗体或窗口上。

处理图像中的Alpha成分
在已包含alpha信息的图像上,用半透明的颜色(即包含alpha成分信息的颜色)进行绘图时,需要考虑GDI+如何计算在得到的图像上每个象素的颜色和alpha成分。对于每个受影响的象素,GDI+都需要把已有的颜色和alpha与绘图操作的颜色和alpha合并起来,生成具有我们希望的效果的颜色和alpha。
GDI+用两种方式计算受影响象素的新颜色:
绘图操作的颜色和alpha可以与已有的颜色和alpha混和起来,创建出依赖于两种颜色和alpha的效果 (颜色混和)
另外,绘图颜色和alpha还可以简单的改写象素中已有的颜色和alpha(后一种颜色覆盖前一种)
我们可以通过Graphics类的CompositingMode属性,来控制绘图操作是混和图像,还是它的alpha信息改写图像。该属性包含两个值:SourceCopy(改写)和SourceOver(混和)

Bitmap类还提供了GetPixel方法和Setpixel方法来获取和设置单个象素点的颜色。

为整个图像设置alpha
ColorMatrix类可以进行颜色转换,它是一个5×5的矩阵用来转换ARGB的值,第五个值W总是为1。单位颜色矩阵如下:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
如果要设置图像的alpha成分为60%,则可以使用如下矩阵:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 0.6 0
0 0 0 0 1
在设置完ColorMatrix后,我们使用ImageAttributes对象,把颜色矩阵赋予ImageAttributes对象的一个属性,最后使用ImageAttributes对象绘制图像。就得到我们想要的效果。

播放GIF动画
下面的例子在Form上播放了一个名为5.gif的动画文件
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

protected override void OnLoad(EventArgs e)
{
mBitmap = new Bitmap("5.gif");
ImageAnimator.Animate(mBitmap, new EventHandler(OnFrameChanged));
base.OnLoad(e);
}

private void OnFrameChanged(object sender, EventArgs e)
{
this.Invalidate();
}

protected override void OnPaint(PaintEventArgs e)
{
ImageAnimator.UpdateFrames();
e.Graphics.DrawImage(mBitmap, new Point(0, 0));
base.OnPaint(e);
}

private Bitmap mBitmap;
}
转换和压缩图片
下面的代码将1.bmp转换为1.jpg
Bitmap bmp = new Bitmap("1.bmp");
bmp.Save("1.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
下面的代码还对图片进行了压缩,压缩率为25%
ImageCodecInfo ici;
System.Drawing.Imaging.Encoder enc;
EncoderParameter ep;
EncoderParameters epa;

ici = GetEncoderInfo("image/jpeg");
enc = System.Drawing.Imaging.Encoder.Quality;
epa = new EncoderParameters(1);

ep = new EncoderParameter(enc, 25L);
epa.Param[0] = ep;

Bitmap bmp = new Bitmap("1.bmp");
bmp.Save("1.jpg", ici, epa);

private ImageCodecInfo GetEncoderInfo(string mimeType)
{
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for (int j = 0; j < encoders.Length; j++)
{
if (encoders[j].MimeType == mimeType)
{
return encoders[j];
}
}
return null;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: