GDI+之图像操作

GDI+开发教程 六 图像介绍及处理 BMP 图像文件格式是 Microsoft 为其 Windows 环境设置的标准图像格式。一个Windows 的 BMP 位图实际上是一些和显示像素相对应的位阵列,它有两种类型:一种称之为 GDI 位图,另一种是 DIB 位图(Device-Independent Bitmap)。GDI 位图包含了一种和Windows 的 GDI 模块有关的 Windows 数据结构,该数据结构是与设备有关的,故此位图又称为 DDB 位图(Device-Dependent Bitmap)。 阅读详情

在GDI+中,对图像的处理主要靠两个类,Image类和Bitmap类,Bitmap类是在Image类的基础上派生出来的。这里主要讲Image类的使用,Image类支持对BMP, GIF, JPEG, PNG, TIFF, 和 EMF,尤其注意,在PNG图像中,包含ALPHA通道,所以能实现不规则图像;

一、图像的打开与显示

图像打开
我们在前言部分已经讲到,在GDI+中,对图像的处理主要靠两个类,Image类和Bitmap类,在Image类的构造函数中,可以直接加载图片供开发者使用,其加载方式为:

[cpp]  view plain copy
  1. Image(filename, useEmbeddedColorManagement)   
  2. Image(stream, useEmbeddedColorManagement) ;//这个不讲了,在一般不用,只在剪切保存图片时有用  
参数说明:
filename:[in]
文件名,(可以是绝对地址,也可以是相对地址)
useEmbeddedColorManament:[in]是否使用在保存在图片中的色彩校正信息(如ICM、Gamma较正),该参数默认值为FALSE;

显示图片

对于图像文件的显示,GDI+主要使用DrawImage函数来完成。DrawImage函数是GDI+功能最强大、调用方式最为灵活的函数中的一种。能够实现在GDI中使用BitBlt函数不能实现的功能(如图片的任意角度旋转、倒置及插值运算),看下DrawImage的形式:

[cpp]  view plain copy
  1. DrawImage(Image* image, Point* destPoints, INT count)   
  2. DrawImage(Image* image, PointF* destPoints, INT count)   
  3. DrawImage(Image* image, Point* destPoints, INT count, INT srcx, INT srcy, INT srcwidth, INT srcheight, Unit srcUnit, ImageAttributes* imageAttributes, DrawImageAbort callback, VOID* callbackData)   
  4. DrawImage(Image* image, PointF* destPoints, INT count, REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight, Unit srcUnit, ImageAttributes* imageAttributes, DrawImageAbort callback, VOID* callbackData)   
  5. DrawImage(Image* image, Rect& destRect, INT srcx, INT srcy, INT srcwidth, INT srcheight, Unit srcUnit, ImageAttributes* imageAttributes, DrawImageAbort callback, VOID* callbackData)   
  6. DrawImage(Image* image, RectF& destRect, REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight, Unit srcUnit, ImageAttributes* imageAttributes, DrawImageAbort callback, VOID* callbackData)   
  7. DrawImage(Image* image, Point& point)   
  8. DrawImage(Image* image, PointF& point)   
  9. DrawImage(Image* image, Rect& rect)   
  10. DrawImage(Image* image, RectF& rect)   
  11. DrawImage(Image* image, INT x, INT y)   
  12. DrawImage(Image* image, REAL x, REAL y)   
  13. DrawImage(Image* image, INT x, INT y, INT srcx, INT srcy, INT srcwidth, INT srcheight, Unit srcUnit)   
  14. DrawImage(Image* image, REAL x, REAL y, REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight, Unit srcUnit)   
  15. DrawImage(Image* image, INT x, INT y, INT width, INT height)   
  16. DrawImage(Image* image, REAL x, REAL y, REAL width, REAL height)   
呃,上面的重载形式太多了,看得眼花缭乱,不过都是一种重载形式,由于变量的不同所以会出现两个重载函数,把相同的给咔嚓掉,最后实际就是下面几种:

[cpp]  view plain copy
  1. DrawImage(Image* image, PointF* destPoints, INT count)   
  2. DrawImage(Image* image, PointF* destPoints, INT count, REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight, Unit srcUnit, ImageAttributes* imageAttributes, DrawImageAbort callback, VOID* callbackData)   
  3. DrawImage(Image* image, Rect& destRect, INT srcx, INT srcy, INT srcwidth, INT srcheight, Unit srcUnit, ImageAttributes* imageAttributes, DrawImageAbort callback, VOID* callbackData)   
  4. DrawImage(Image* image, PointF& point)   
  5. DrawImage(Image* image, RectF& rect)   
  6. DrawImage(Image* image, INT x, INT y)   
  7. DrawImage(Image* image, INT x, INT y, INT srcx, INT srcy, INT srcwidth, INT srcheight, Unit srcUnit)   
  8. DrawImage(Image* image, INT x, INT y, INT width, INT height)   
其它先不看,我们看一种最难的形式:
[cpp]  view plain copy
  1. DrawImage(Image* image, Rect& destRect, INT srcx, INT srcy, INT srcwidth, INT srcheight, Unit srcUnit, ImageAttributes* imageAttributes, DrawImageAbort callback, VOID* callbackData)   
参数说明:
image:[in]图像文件对象;
destRect:[in]目标显示区域
srcx:[in]要截取的目标位置,在原图中的X点坐标
srcy:[in]要截取的目标位置,在原图中的Y坐标
srcwidth:[in]要截取的目标图像的宽度
srcheight:[in]要截取的目标图像的高度

注意:由于是截取一块图像作为显示图像在目标区域中显示,所以这就出现了问题
1、当截取的图像比目标区域小呢?
这时,就是将截取的图像拉伸,以至完全填充到目标区域
2、当截取的图像比目标区域大呢?
这里,就会将截取的图像缩小并平铺到目标区域中,并不会截取一部分显示

看示例:(放大、缩小)

[cpp]  view plain copy
  1. Image image(L"wlh.bmp");  
  2. UINT width=image.GetWidth();  
  3. UINT height=image.GetHeight();  
  4. //原图显示  
  5. graphics.DrawImage(&image,RectF(0,0,width,height));  
  6. //缩小并平铺  
  7. graphics.TranslateTransform(width+10,0);  
  8. graphics.DrawImage(&image,RectF(0,0,width/2,height/2-40));  
  9. //放大并平铺,将在原图指定区域截取的图像,填充到目标区域中,填充时采用了缩放模式  
  10. graphics.TranslateTransform(width/2+10,0);  
  11. RectF destinationRect(0,0,1.4*width,1.4*height);  
  12. graphics.DrawImage(&image,destinationRect,20,20,width/2,height,UnitPixel);  

二、 使用插补模式控制图形缩放质量

首先考虑两个问题:
1、在拉伸图像时,假设图像会被拉大好几倍,如何用原来的那些像素点来填充拉大后的图像,就出现了问题,比如,原来一个像素点,在拉大图像后,这个像素点周围会变得空白,如何运用算法填充这些空白呢?
2、在缩小图像时,同样假设图像缩小为原来的1/5,那么就说明在原图像中,每5个像素,会被整合成一个像素,那这些像素怎么整合呢?哪种整合方法更好一点呢?

以上这两上放、大缩小时,如何填充被放大的空间,如何整合缩小的像素,这些问题,这就是插补模式要考虑的问题,插补模式又称为“插值模式”,是指如何计算两个终点之间的中间值。也就是定义了很多种算法,这些算法的效果决定了缩放后图像的质量。
GDI+中使用Graphics类的SetInterpolationMode(设置插值模式)函数来指定插补算法。看下函数定义:

[cpp]  view plain copy
  1. Status SetInterpolationMode(  
  2.   InterpolationMode interpolationMode  
  3. );  
其中 InterpolationMode 是个枚举类,枚举了几种插补模式,定义如下:
[cpp]  view plain copy
  1. enum InterpolationMode{  
  2.   InterpolationModeInvalid = QualityModeInvalid,//插值无效  
  3.   InterpolationModeDefault = QualityModeDefault,//默认模式  
  4.   InterpolationModeLowQuality = QualityModeLow,//低质量插值法  
  5.   InterpolationModeHighQuality = QualityModeHigh,//高质量插值法  
  6.   InterpolationModeBilinear,//双线性插值法  
  7.   InterpolationModeBicubic,//双三次插值法  
  8.   InterpolationModeNearestNeighbor,//最临近插值法  
  9.   InterpolationModeHighQualityBilinear,//高质量双线性插值法  
  10.   InterpolationModeHighQualityBicubic//高质量双三次插值法  
  11. };  
看下面这个图片,显示了将一个图像使用不同的插值算法放大两倍后的结果:

看一个简单的应用的例子吧:(最临近插值法)
[cpp]  view plain copy
  1. Image image(L"bird.bmp");  
  2. UINT width=image.GetWidth();  
  3. UINT height=image.GetHeight();  
  4. Matrix matrix;  
  5. graphics.GetTransform(&matrix);  
  6. graphics.DrawImage(&image,RectF(0,0,width,height));  
  7.   
  8. graphics.TranslateTransform(width+10,0);  
  9. RectF destinationRect(0,0,2*width,2*height);  
  10. graphics.SetInterpolationMode(InterpolationModeNearestNeighbor);  
  11. graphics.DrawImage(&image,destinationRect,20,20,width/2,height/2,UnitPixel);  

结论:由上面的所有扩大结果来看,只有“最临近插值法”会产生马赛克,而PS和其它的图像处理工具都是用的它。可能是因为它的资源消耗比较小,要注意,不同插值模式对系统资源的消耗也不同,其中高质量双三次插值方式对系统资源的消耗最大。

三、图像操作

图片的简单旋转

利用Bitmap或Image对象的RotateFilip函数就可以实现图像的旋转和翻转了。该函数的调用方法为:

[cpp]  view plain copy
  1. Status RotateFlip(  
  2.   RotateFlipType rotateFlipType  
  3. );  
其中RotateFlipType是一个枚举类,枚举了8种旋转方式,看下定义:
[cpp]  view plain copy
  1. enum RotateFlipType{  
  2.   RotateNoneFlipNone = 0,//不旋转不翻转  
  3.   Rotate90FlipNone = 1,//旋转90度不翻转  
  4.   Rotate180FlipNone = 2,//旋转180度不翻转  
  5.   Rotate270FlipNone = 3,//旋转270度不翻转  
  6.   RotateNoneFlipX = 4,//不旋转水平翻转  
  7.   Rotate90FlipX = 5,//旋转90度水平翻转  
  8.   Rotate180FlipX = 6,//旋转180度水平翻转  
  9.   Rotate270FlipX = 7,//旋转270度水平翻转  
  10.   RotateNoneFlipY = Rotate180FlipX,//往下的这些跟上面的效果都是一样的,所以一般都不用下面的几个  
  11.   Rotate90FlipY = Rotate270FlipX,  
  12.   Rotate180FlipY = RotateNoneFlipX,  
  13.   Rotate270FlipY = Rotate90FlipX,  
  14.   RotateNoneFlipXY = Rotate180FlipNone,  
  15.   Rotate90FlipXY = Rotate270FlipNone,  
  16.   Rotate180FlipXY = RotateNoneFlipNone,  
  17.   Rotate270FlipXY = Rotate90FlipNone  
  18. };  
看下效果:

看个简单示例吧(RotateNoneFlipX--不旋转水平翻转)
[cpp]  view plain copy
  1. Image image(L"bird.bmp");  
  2. UINT width=image.GetWidth();  
  3. UINT height=image.GetHeight();  
  4. Matrix matrix;  
  5. graphics.GetTransform(&matrix);  
  6. graphics.DrawImage(&image,RectF(0,0,width/2,height/2));  
  7.   
  8. graphics.SetTransform(&matrix);  
  9. graphics.TranslateTransform(width/2+10,0);  
  10. Image *img2=image.Clone();  
  11. img2->RotateFlip(RotateNoneFlipX);  
  12. graphics.DrawImage(img2,RectF(0,0,width/2,height/2));  

使用缩略图

GDI+中可以定制缩略图,具体办法是使用Image类的GetThumbnailImage来实现,该函数的调用方法为:

[cpp]  view plain copy
  1. Image* GetThumbnailImage(  
  2.   UINT thumbWidth,  
  3.   UINT thumbHeight,  
  4.   GetThumbnailImageAbort callback,  
  5.   VOID* callbackData  
  6. );  
参数说明:
thumbWidh、thumbHeightt:[in]指明需要建立的缩略图宽度和高度,在IMG中不会自动保持宽高比,会根据指定的高度和宽度完全填充;
callback、callbackData:[in]建立缩略图时要用到的回调函数及回调函数中数据的存放地址;在GDI+1.0版中不能使用此功能;注意XP中使用也是1.0版
注意:这里虽是指获取缩略图,但当所指区域比原图大时,就会把原图放大,与DrawImage指定目标区域,没什么区别;

示例:

[cpp]  view plain copy
  1. graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);  
  2. Image img(L"wlh.bmp");  
  3. float shear=img.GetHeight()/img.GetWidth();//获取高/宽比,以至缩放时不变形  
  4. Image *pThumbnail=img.GetThumbnailImage(80,80*shear,NULL,NULL);//高度乘以高宽比  
  5.   
  6. TextureBrush picBrush(pThumbnail);  
  7. graphics.FillEllipse(&picBrush,RectF(10,10,400,200));  

克隆图片

克隆复制是GDI+中的新概念,对图片克隆的范围可以是整体,也可以是局部的。实现克隆的办法是使用Bitmap类/Image类的Clone成员函数;需要注意的是,Bitmap类可以实现局部克隆和整体克隆,而Image类只能整体克隆;
我们看下Bitmap类的Clone函数:

[cpp]  view plain copy
  1. Clone()   
  2. Clone(Rect& rect, PixelFormat format)   
  3. Clone(RectF& rect, PixelFormat format)   
  4. Clone(INT x, INT y, INT width, INT height, PixelFormat format)   
  5. Clone(REAL x, REAL y, REAL width, REAL, height, PixelFormat format)   
参数说明:
rect:[in]要克隆的区域,指在原图中的坐标区域矩形;
x,y:[in]要克隆区域的X,Y坐标;
width,height:[in]要克隆区域的宽度和高度;
看下示例(将图片通过克隆,分成四块):
[cpp]  view plain copy
  1. Bitmap bmp(L"wlh.bmp");  
  2. INT height=bmp.GetHeight();  
  3. INT width=bmp.GetWidth();  
  4.   
  5. RectF dest[4];  
  6. dest[0]=RectF(0,0,width/2,height/2);  
  7. dest[1]=RectF(width/2,0,width/2,height/2);  
  8. dest[2]=RectF(0,height/2,width/2,height/2);  
  9. dest[3]=RectF(width/2,height/2,width/2,height/2);  
  10. //把原图像分为分四块克隆  
  11. Bitmap *s[4];  
  12. s[0]=bmp.Clone(dest[0],PixelFormatDontCare);  
  13. s[1]=bmp.Clone(dest[1],PixelFormatDontCare);  
  14. s[2]=bmp.Clone(dest[2],PixelFormatDontCare);  
  15. s[3]=bmp.Clone(dest[3],PixelFormatDontCare);  
  16. //绘图  
  17. graphics.DrawImage(s[0],RectF(0,0,width/2,height/2));  
  18. graphics.DrawImage(s[1],RectF(width/2+10,0,width/2,height/2));  
  19. graphics.DrawImage(s[2],RectF(0,height/2+10,width/2,height/2));  
  20. graphics.DrawImage(s[3],RectF(width/2+10,height/2+10,width/2,height/2));  

投射与倾斜
在前面我们讲了,在DrawImge可以指定目标区域矩形,然后图像就会自适应这个矩形,所以按说我们可以用指定目标矩形的方式来实现下图的效果;


但是,我们得一个个计算这些矩形的四个点坐标,很难,还好,DrawImage为我们提供了一个重载函数,函数如下:

[cpp]  view plain copy
  1. Status DrawImage(  
  2.   Image* image,  
  3.   const Point* destPoints,  
  4.   INT count  
  5. );  
参数说明:
image:[in]图像对象
destPoints:[in]目标区域的点的组合,这里只包含三个点,左上,右上,左下,对于第四个点的坐标,GDI+会根据平行四边形原理自动计算位置;
count:[in]destPoints数组里的点的个数,必须等于3

示例:(实现上面的三面立方体)

[cpp]  view plain copy
  1. //清空原背景色,然后将背景色换为绿色  
  2. graphics.Clear(Color::Green);  
  3. //设置填充模式  
  4. graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);  
  5. Image img(L"wlh.bmp");  
  6. INT left=100;  
  7. INT top=200;  
  8. INT width=img.GetWidth();  
  9. INT height=img.GetHeight();  
  10. //正面  
  11. PointF desFace[]={  
  12.     PointF(left,top),  
  13.     PointF(left+width,top),  
  14.     PointF(left,top+width),  
  15. };  
  16. graphics.DrawImage(&img,desFace,3);  
  17. //上面投射  
  18. PointF destTop[]={  
  19.     PointF(left+width/2,top-width/2),  
  20.     PointF(left+width/2+width,top-width/2),  
  21.     PointF(left,top),  
  22. };  
  23. graphics.DrawImage(&img,destTop,3);  
  24. //侧面投射  
  25. PointF desRight[]={  
  26.     PointF(left+width,top),  
  27.     PointF(left+width/2+width,top-width/2),  
  28.     PointF(left+width,top+width)  
  29. };  
  30. graphics.DrawImage(&img,desRight,3);  

调整图像的色彩信息

色彩调整,主要靠ImageAttributes类中的函数来操作的,所以这里也就是对ImageAttributes类中各函数功能的讲解;这里说色彩较正,其实就是通过色彩变换矩阵,对色彩所进行的操作。
一、启用与禁用色彩校正

使用色彩变换矩阵,程序开发人员可以使用ImageAttributes对象修改在绘图平面上的图片输出行为:使用修改后的色彩对应关系。在修改过程中,可以临时禁用或启用色彩校正行为。ImageAttributes类的成员函数SetNoOp和ClearNoOp实现了对色彩校正的临时关闭与启用,其函数调用格式为:

[cpp]  view plain copy
  1. Status SetNoOp(  
  2.                ColorAdjustType type  
  3.                );  
  4. Status ClearNoOp(  
  5.                  ColorAdjustType type  
  6.                  );  

其中,ColorAdjustType是个枚举类,指明了几种色彩调整对象;

[cpp]  view plain copy
  1. enum ColorAdjustType{  
  2.   ColorAdjustTypeDefault,//匹配全部对象  
  3.   ColorAdjustTypeBitmap,//仅匹配图像,虽然这里用的是Bitmap,但不仅限于BMP图像,只要是图像都用这个  
  4.   ColorAdjustTypeBrush,//仅匹配画刷  
  5.   ColorAdjustTypePen,//仅匹配画笔  
  6.   ColorAdjustTypeText,//仅匹配对文字的调整  
  7.   ColorAdjustTypeCount,//不用  
  8.   ColorAdjustTypeAny//不用,最后两个是不用的;  
  9. };  
上代码,看示例:
[cpp]  view plain copy
  1. Image img(L"wlh.bmp");  
  2. int width=img.GetWidth();  
  3. int height=img.GetHeight();  
  4. //原图  
  5. graphics.DrawImage(&img,RectF(0,0,width,height));  
  6. //应用色彩变换  
  7. graphics.TranslateTransform(width+10,0);  
  8. ColorMatrix colorMatrix={  
  9.     0.0f,1.0f,0.0f,0.0f,0.0f,  
  10.     0.0f,1.0f,0.0f,0.0f,0.0f,  
  11.     0.0f,0.0f,1.0f,0.0f,0.0f,  
  12.     0.0f,0.0f,0.0f,1.0f,0.0f,  
  13.     0.0f,0.0f,0.0f,0.0f,1.0f  
  14. };  
  15. ImageAttributes imgattr;  
  16. imgattr.SetColorMatrix(&colorMatrix,ColorMatrixFlagsDefault,ColorAdjustTypeBitmap);  
  17. graphics.DrawImage(&img,RectF(0,0,img.GetWidth(),img.GetHeight()),0,0,img.GetWidth(),img.GetHeight(),UnitPixel,&imgattr);  
  18. //清除对图像的变换  
  19. imgattr.SetNoOp(ColorAdjustTypeBitmap);  
  20. graphics.TranslateTransform(width+10,0);  
  21. graphics.DrawImage(&img,RectF(0,0,img.GetWidth(),img.GetHeight()),0,0,img.GetWidth(),img.GetHeight(),UnitPixel,&imgattr);  
  22. //清除刚才的清除操作  
  23. imgattr.ClearNoOp(ColorAdjustTypeBitmap);  
  24. graphics.TranslateTransform(width+10,0);  
  25. graphics.DrawImage(&img,RectF(0,0,img.GetWidth(),img.GetHeight()),0,0,img.GetWidth(),img.GetHeight(),UnitPixel,&imgattr);  

二、设置透明色范围(ImageAttributes::SetColorKey)

在上面的应用中,我们可以通过对图像的图像逐个像素操作将指定的颜色设定为透明色,也可以通过ColorMap将指定的几个颜色替换为其它颜色,在这里,是另一种设定图片透明的方法——设定关键色(ColorKey),关键色就是指要设为透明的颜色值。通过ImageAttributes类的SetColorKey方法,定义如下:

[cpp]  view plain copy
  1. Status SetColorKey(  
  2.   const Color& colorLow,  
  3.   const Color& colorHigh,  
  4.   ColorAdjustType type  
  5. );  
参数说明:
colorLow:[in]透明色的最低值;
colorHigh:[in]透明色的最高值;
type:[in]指定要设定关键色的对象
;
注意:假设colorLow设定为Color(100, 95, 30),colorHigh设定为:Color(250, 245, 60);那么对于颜色值Color(x,y,z);如果100<x<250  and 95<y<245 and 30<z<60,那么它就会被设为透明色;
示例:(去除王力宏图片的背景,背景色我用PS加了个渐变,从Color(200,200,200)到Color(255,255,255),所以这个范围也是要设定为关键色的范围)
代码:
[cpp]  view plain copy
  1. Image img(L"wlh2.bmp");  
  2. graphics.Clear(Color(255,0,255,0));  
  3. //绘制原图  
  4. graphics.DrawImage(&img,RectF(0,0,img.GetWidth(),img.GetHeight()));  
  5. //设置透明色范围  
  6. graphics.TranslateTransform(img.GetWidth()+10,0);  
  7. ImageAttributes imgAttributes;  
  8. imgAttributes.SetColorKey(Color(255,200,200,200),Color(255,255,255,255),ColorAdjustTypeBitmap);  
  9. graphics.DrawImage(&img,RectF(0,0,img.GetWidth(),img.GetHeight()),0,0,img.GetWidth(),img.GetHeight(),UnitPixel,&imgAttributes);  

注意:在图片上也可以看得到,王的鼻尖处也变成了透明色,这是因为它的色彩值范围在设定的ColorKey的范围内
C#.net 图像处理基础知识入门级 入门基础必备: C#类库的GDI可以支持图像处理 bitmap主要是处理图片的 直接利用文件名创建一个对象 利用已有的对象来创建 或者在内存里创建 利用宽,高创建 FromFile的方式创建 更一般的图像处理,可以用图像的像素处理: 用GetPixel(x,y)得到目标像素点的颜色的方法,用这种方式比较慢。 更一般的方法在处理图像是用指针 C#是支持指针的,但是一... 阅读详情

相关推荐

Graphics::DrawImage()函数的使用

Graphics 有18个DrawImage()重载函数,用于绘制图像,其中值得注意的有:   Status DrawImage(Image *image, INT x, INT y);          这是使用很方便一个函数,用于将图像绘制在(x,y)

目前打算换一个工作,有招聘windows c++方向的也欢迎联系,北京、济南 最好 3万+

GDI+学习及代码总结之------图像的基本处理

图像的基本操作 在GDI+中,对图像的处理主要靠两个类,Image类和Bitmap类,Bitmap类是在Image类的基础上派生出来的。这里主要讲Image类的使用,Image类支持对BMP, GIF, JPEG, PNG, TIFF, 和 EMF,尤其注意,在PNG图像中,包含ALPHA通道,所以能实现不规则图像; 一、图像的打开与显示 图像打开 我们在前言部分已经讲到,在GDI+中

启舰 3万+

winform自定义控件(gdi+)(14)——绘制图像(DrawImage)

1、显示图像 Graphics g = e.Graphics; Bitmap bmp = new Bitmap("1.jpg"); g.DrawImage(bmp,0,0);//屏幕上图像的大小为屏幕分辨率和图像分辨率的比值 Console.WriteLine(g.DpiX ); Console.WriteLine(g.DpiY ); Console.WriteLine(bmp.H

qq_34059233的博客 2937

GDI+编程

Image和Bitmap类概述GDI+的Image类封装了对BMP、GIF、JPEG、PNG、TIFF、WMF(Windows元文件)和EMF(增强WMF)图像文件的调入、格式转换以及简单处理的功能。而Bitmap是从Image类继承的一个图像类,它封装了Windows位图操作的常用功能。例如,Bitmap::SetPixel和Bitmap::GetPixel分别用来对位图进行读写像素操作,从而可

1278

65、VB.NET 图像操作与 GDI+ 绘图指南

本博客介绍了在 VB.NET 中使用 GDI+ 进行图像操作与绘图的基础知识。内容涵盖通过剪贴板交换图像、GDI+ 绘图的基本对象(如 Graphics、Pen、Brush)、基本绘图步骤以及综合应用示例,帮助开发者掌握如何在 VB.NET 中创建丰富的图形界面。

carrot的博客 102

GDI+位图操作与图像处理技巧

本文深入探讨了在GDI+环境下如何使用.NET进行位图的绘制、旋转、翻转以及像素级别的操作。通过实例代码和图表说明了如何加载、绘制位图,以及如何通过旋转翻转函数和直接访问像素缓冲区来修改图像。同时,文章强调了代码重用和定制的重要性,并提供了关于如何正确管理资源释放的建议。

weixin_42443533的博客 267

GDI+图像操作

在GDI+中,对图像的处理主要靠两个类,Image类和Bitmap类,Bitmap类是在Image类的基础上派生出来的。这里主要讲Image类的使用,Image类支持对BMP, GIF, JPEG, PNG, TIFF, 和 EMF,尤其注意,在PNG图像中,包含ALPHA通道,所以能实现不规则图像; 一、图像的打开与显示 图像打开 我们在前言部分已经讲到,在GDI+中,对图像的处理

crkres9527 596

WPF图像操作报GDI+通用错误?附带即用型修复工程(含XAML/CS完整源码)

WPF项目里一加载图片、保存截图或动态生成图标就弹出‘A generic error occurred in GDI+’,基本不是代码写得不对,而是资源没管好——文件流没关、位图被重复释放、PNG编码器没指定、跨线程碰了BitmapSource,或者路径权限有问题。这个工程直接给出可运行的解决方案:基于.NET Framework 4.5+和.NET Core/5+ WPF环境,包含标准WPF项目结构(MainWindow.xaml + .cs、App.xaml、Converters、ViewModel、I

net55的博客 225

GDI图像基本操作

GDI图像基本操作: 借鉴自:http://blog.youkuaiyun.com/harvic880925/article/details/9129011 实例: void CMFC_GDI_TESTDlg::OnLoadImg() { // 基本变换 CDC* cdc = GetWindowDC(); Gdiplus::Graphics graphics(cdc->GetSafeHdc());

qingzai_的专栏 1437

GDI技术实现图片缩放

本文还有配套的精品资源,点击获取 简介:在Windows编程中,GDI允许开发者进行图形、文本和图像绘制。本示例展示如何运用GDI技术实现图片的放大和缩小功能,这对于GUI应用程序开发尤其重要。基本步骤包括加载图片,创建设备上下文,选择位图,应用图像缩放算法,并进行重绘。使用最近邻插值和双线性插值是常见的缩放技术。为了优化性能,应当注意合理选择插值算法并避免不必要的内存拷贝...

weixin_36184718的博客 1171

深入探讨GDI+与GDI互操作性及其性能优化

在图形应用程序开发中,质量和性能是两个基本要求。本章详细探讨了如何通过绘制事件机制、双缓冲技术以及避免图像自动缩放等方法来编写性能优化的图形应用程序。同时,也讨论了如何在托管环境中使用GDI技术,以及如何通过DllImportAttribute类实现Win32 SDK功能的导入,从而在.NET应用程序中使用GDI+的互操作性。

weixin_35755823的博客 520

通用GUI编程技术——Win32 原生编程实战(二十二)——GDI 位图操作:BitBlt、StretchBlt 与图像处理

本文深入探讨了Win32 GDI编程中的位图操作技术,重点介绍了BitBlt、StretchBlt等核心函数及其应用场景。文章首先分析了DDB与DIB位图的区别,阐述了设备相关位图(DDB)和设备无关位图(DIB)的特点及适用场景。接着详细讲解了兼容DC与内存位图的创建流程,包括CreateCompatibleDC和CreateCompatibleBitmap的正确使用方法,以及位图选入DC的标准操作流程。最后,文章重点解析了BitBlt函数的参数和光栅操作代码(ROP3),为开发者提供了实用的位图处理技术

charlie114514191的博客 606

爬取二手房数据:Python爬虫+Geopy实战,看透房价与地理位置的隐藏关系

哪些区域单价虚高(房源少但单价远高于周边);哪些小区性价比高(靠近地铁/学校,单价低于同地段平均水平);房价与地理位置的量化关系(如距离地铁每远1公里,单价下降多少)。如果想扩展分析范围,可爬取多个城市/区域的数据,对比不同城市的房价差异;或结合时间维度(定期爬取),分析房价的涨跌趋势。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 948

MFC中的GDI/GDI+和双缓冲绘图

1、GDI概述   GDI在全称是Graphics Device Interface,即图形设备接口。是图形显示与实际物理设备之间的桥梁。         GDI使得用户无需关心具体设备的细节,而只需在一个虚拟的环境(即逻辑设备)中进行操作。它的桥梁作用体现在:      (1)用户通过调用GDI函数将逻辑空间的操作转化为具体针对设备驱动程序的调用。      为实现图形设

Invoker's Tower 8084

YoloV8改进策略:轻量级的CloFormer助力Yolov8在速度和精度上实现双双提升

CloFormer是清华大学在今年发表的轻量级主干网络,引入了AttnConv,一种attention风格的卷积算子。所提出的AttnConv使用共享权重来聚合局部信息,并配置精心设计的上下文感知权重来增强局部特征。AttnConv和普通attention的结合使用池化来减少CloFormer中的FLOPs,使模型能够感知高频和低频信息。这篇文章主要向大家讲解如何将CloFormer加入到YoloV8中。论文链接:https://arxiv.org/abs/2303.17803v5。

m0_47867638的博客 4311

OpenClaw实战系列01:OpenClaw接入飞书机器人全接入指南 + Ollama本地大模型

通过 OpenClaw + Ollama + 飞书的组合,我们成功搭建了一个完全私有、免费、可定制的AI助理。它不仅能在日常聊天中提供帮助,还能通过OpenClaw强大的“技能”体系,真正去操作你的电脑、管理文件、甚至执行代码。这套方案将数据留在本地,既保证了隐私安全,又锻炼了动手能力。现在,去给你的AI助理添加更多酷炫的技能吧!

PeterPan的博客 1万+

GDI功能介绍:图形绘制与图像处理

GDI功能介绍:图形绘制与图像处理 目录: 1. 引言 2. C#中的GDI(Graphics Device Interface) - 什么是GDI? - GDI的作用和优势 3. GDI功能分类 - 基本绘图功能 - 文本处理 - 图像处理 4. 示例代码 - 绘制简单图形 - 绘制文本 - 加载和显示图像 5. 总结

没有黑科技 833

抖音 webmssdk 签名算法解析:X-Dynosaur / X-Gnarly / X-Bogus 生成原理

它只依赖设备指纹/环境编码与随机数,与 query 内容无关,因此可以独立于 Dynosaur/Gnarly 生成。

猫敷雪 197

利用GDI+实现BMP、JPEG、GIF图像格式的转换

在Visual C++6.0中,实现各种类型的类型的图像转换是比较复杂的,有时还需要用户了解图像的各种格式,以及图像的编码、解码算法。使用GDI+,用户则可以非常方便地实现图像类型的转换。下面就编写一个实例实现BMP、JPEG、GIF图像格式的相互转换。 在VS中使用GDI+需注意的问题: 1.下载GDI+包文件 2.引用Gdiplus.h头文件 3.引用Gdiplus命名空间 (1)创

大道至简,知易行难 1872

【Scratch考级100图】图01-等级考试scratch绘 画正方形

一、案例介绍 小朋友们应该在数学课或者平时生活中有了解过正方形,正方形在我们生活中到处可见,那我们如果通过Scratch软件来绘制一个正方形呢,我们一起来学习一下吧,在舞台正中央绘制一个边长为200的正方形,要求: 1、围绕舞台中心绘制正多边形,均匀分布在四个象限中 2、正方形边长为200个单位,线条粗细、颜色自定 3、利用画笔绘制正方形,不能有多余的线条 二、案例演示 【Scratch案例演示】Scratch图1-画正方形 三、案例分析 当我们点击小绿旗启动程序后,舞台上会出现一个画

青少年编程学习指导 2670

万字长文解密:SAP Fiori 首屏加载缓慢背后的真相

什么是一个健康理想的 Fiori 首次加载状态?FLP 首页不臃肿,用户默认看见的内容不多但足够用缓存作业按规则运行,冷启动不至于每次都从零开始应用首屏只读必要数据,UI5 资源经过 preload,视图异步加载OData 服务字段克制、分页合理、缓存分层清楚后台 CDS 与 HANA 只为当前屏幕做最必要的工作。只要这些标准同时满足,用户第一次打开 Fiori 页面的体感通常会从明显卡顿变成可接受甚至顺滑。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 557

Windows GDI+

GDI:Graphics Device Interface,即图形设备接口,是Windows API的一个重要组成部分。它是Windows图形显示程序与实际物理设备之间的桥梁,GDI使得用户无需关心具体设备的细节,而只需在一个虚拟的环境(即逻辑设备)中进行操作。它的桥梁作用体现在: (1)用户通过调用GDI函数将逻辑空间的操作转化为具体针对设备驱动程序的调用。 为实现图形设备无关性,Windo...

$firecat利白的代码足迹$ 1343

高效与灵活相结合:Verilog编写的跨时钟域循环缓冲控制器解析

循环缓冲区,也被称作循环队列、环形缓冲区,是一种数据结构,其主要特性是使用一个固定大小的缓冲区作为数据的存储空间,这个缓冲区在逻辑上被视作是首尾相接的。虽然Verilog是一种常用的硬件描述语言,被广泛应用在FPGA和ASIC设计中,但是在描述循环缓冲区时,它并没有提供一种直接且灵活的方式来指定循环缓冲区的参数,如字长、缓冲区深度、缓冲区数量等。这给硬件设计带来了一定的不便。同时,该控制器的设计也充分考虑了硬件资源的利用率,通过优化的算法和数据结构,使得在实现高性能的同时,也能够有效地节省硬件资源。

qq_38334677的博客 1221

Windows GDI和GDI+编程实例剖析(1)

Windows GDI和GDI+编程实例剖析(1) 作者:宋宝华 e-mail:21cnbao@21cn.com 1.基本概念 GDI在Windows中定义为Graphics Device Interface,即图形设备接口,是Windows API(Application Programming Interface)的一个重要组成部分。它是Windows图形显示程序与实际物理设备之间

wiSCADA 2084

20、微电网系统的系统框架、建模与控制架构解析

本文详细解析了微电网系统的系统框架、建模方法以及控制架构。文章首先介绍了在系统的系统(SoS)框架下,微电网如何通过微控制器(MC)和微电网中央控制器(MGCC)协调运行,并支持并网与孤岛模式下的高效能量管理。随后,针对微电网的关键组件,包括微涡轮机、光伏太阳能电池和风力涡轮机,提供了详细的数学建模分析。最后,探讨了微电网的控制架构设计,涵盖分层控制和共识控制策略,以实现系统的高效、稳定运行,满足日益增长的能源需求与市场要求。

elastic6hunter的博客 206

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

GDI和GDI+对象的相互转换(转)

一、CDC到Graphics只要这样: Graphics g(pDC->GetSafeHdc());//只要能构造CDC句柄的MFC对象都可以  //CClientDC、CPaintDC,也都可以 二、CBitmap到Graphics需要创建一个内存位图设备: CDC MemDC;CBitmap MemBitmap;MemDC.CreateCompatibleDC(pDC);M...

weixin_30865427的博客 98

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

上一篇: GDI+ 之变换
下一篇: 网络沟通方案
htt9931
博客等级 码龄24年 43粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值