C语言版GDI+应用例子 -- 制作水印图片

    本文介绍一个利用C语言版GDI+制作水印图片的例子,下面是程序代码:

#include "../../SampleCode/comcode/Application.h" #pragma hdrstop #define ID_SAVE 101 PGpBitmap bitmap; PGpBitmap photo; PGpBitmap watermark; INT wmWidth, wmHeight; INT phWidth, phHeight; HFONT hFont = NULL; ColorMatrix colorMatrix = {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}; void OnCreate(void) { PGpImageAttr attr; PGpFont font; PGpBrush brush; PGpStrFormat format; PGpGraphics g; float x, y; Rect dRect; RectF fRect; HWND hButton; hFont = CreateFont(14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, GB2312_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DECORATIVE, TEXT("宋体")); hButton = CreateWindow(TEXT("Button"), TEXT("保存"), WS_CHILD | WS_VISIBLE, 400, 204, 80, 25, Handle, (HMENU)ID_SAVE, hInstance, NULL); SendMessage(hButton, WM_SETFONT,(WPARAM)(hFont), 0); // 读取原始图片 photo = BitmapFromFile(L"..//..//Media//100_0349.jpg", FALSE); phWidth = ImageGetWidth(photo); phHeight = ImageGetHeight(photo); // 读取水印图片 watermark = BitmapFromFile(L"..//..//Media//Watermark.bmp", FALSE); wmWidth = ImageGetWidth(watermark); wmHeight = ImageGetHeight(watermark); // 建立一个新的位图,分辨率为72 bitmap = BitmapCreate(phWidth, phHeight, PixelFormat32bppARGB); BitmapSetResolution(bitmap, 72, 72); // 建立新位图的画布,并设置图像显示质量和文本显示质量 g = GraphicsFromImage(bitmap); GraphicsSetSmoothingMode(g, SmoothingModeAntiAlias); GraphicsSetTextRenderingHint(g, TextRenderingHintAntiAlias); /* 在画布上画原始图像 */ GraphicsDrawImage(g, photo, 0, 0, phWidth, phHeight); /* 画水印原始图像 */ // 建立一个图像显示属性对象 attr = ImageAttrCreate(); // 设置透明颜色为水印图片四角的底色,水印图显示为圆角图片 ImageAttrSetColorKey(attr, 0xff00ff00, 0xff00ff00, ColorAdjustTypeBitmap); // 设置水印图片不透明度为0.3 ImageAttrSetColorMatrix(attr, &colorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap); // 在画布左上角画原始水印图 dRect = MakeRect(10, 10, wmWidth, wmHeight); GraphicsDrawImageRectRect(g, watermark, &dRect, 0, 0, wmWidth, wmHeight, UnitPixel, attr); /* 在画布下方居中画文本 */ // 建立字体对象 font = FontCreate(L"arial", 16, FontStyleBold); // 建立画刷对象 brush = SolidBrushCreate(0x99000000); // 建立文本格式对象 format = StrFormatCreate(); // 设置文本居中显示 StrFormatSetAlignment(format, StringAlignmentCenter); // 画文本阴影 fRect = MakeRectF(phWidth / 2 + 1, phHeight - 26 + 1, 0, 0); GraphicsDrawString(g, L"Copyright © 2010 - Maozefa", font, brush, &fRect, format); // 画文本 fRect = MakeRectF(phWidth / 2, phHeight - 26, 0, 0); SolidBrushSetColor(brush, 0x99ffffff); GraphicsDrawString(g, L"Copyright © 2010 - Maozefa", font, brush, &fRect, format); ImageAttrDelete(attr); StrFormatDelete(format); FontDelete(font); BrushDelete(brush); GraphicsDelete(g); } void OnDestroy(void) { if (hFont) DeleteObject(hFont); ImageDelete(bitmap); ImageDelete(photo); ImageDelete(watermark); } void OnCommand(WORD NotifyCode, WORD itemID, HWND ctlHandle) { EncoderParameters parameters; UINT quality = 100; GUID clsid; if (itemID != ID_SAVE) return; // 设置图像品质编码参数 parameters.Count = 1; parameters.Parameter[0].Guid = EncoderQuality; parameters.Parameter[0].Type = EncoderParameterValueTypeLong; parameters.Parameter[0].NumberOfValues = 1; // 设置参数的值:品质等级,最高为100,图像文件大小与品质成正比 parameters.Parameter[0].Value = &quality; // 保存水印图片 if (GetEncoderClsid(L"image/jpeg", &clsid)) ImageSaveToFile(bitmap, L"d://WatermarkPhoto.jpg", &clsid, ¶meters); } void OnPaint(HDC DC) { PGpGraphics g = GraphicsCreate(DC); // GDI+ 画布 // 显示原始图片 GraphicsDrawImage(g, photo, 0, 0, phWidth, phHeight); // 显示水印原始图片 GraphicsTranslate(g, 0, phHeight + 5, MatrixOrderPrepend); GraphicsDrawImage(g, watermark, 0, 0, wmWidth, wmHeight); // 显示带水印和文本的图像 GraphicsTranslate(g, phWidth, -(phHeight + 5), MatrixOrderPrepend); GraphicsDrawImage(g, bitmap, 0, 0, phWidth, phHeight); GraphicsDelete(g); } WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // 这里使用了双缓冲画窗口 */ InitApplication(hInstance, nCmdShow, TRUE); CreateProc = OnCreate; DestroyProc = OnDestroy; PaintProc = OnPaint; CommandProc = OnCommand; return RunApplication(TEXT("C语言Gdiplus演示例子 -- 水印图片"), 518, 280); } //---------------------------------------------------------------------------

    本例子制作水印图片的步骤:

    1、打开原始图片和原始水印图片;

    2、建立一个新的图像,即要制作的水印图片,其大小等同于原始图片;

    3、画原始图片到新图像;

    4、利用图像显示属性对象设置原始水印图片关键颜色,将其四个角的绿色像素置为透明色,这样显示的图像为圆角形状;

    5、利用图像显示属性对象设置原始水印图片颜色矩阵,使其按30%的不透明度显示;

    6、根据设置好的图像显示属性对象显示原始水印图片到新图像左上角;

    7、设置文本显示格式对象为文本居中显示;

    8、以版权文本显示中心坐标偏右下1像素,用0x99000000颜色在新图像显示版权文本阴影,颜色中的0x99为文本阴影颜色不透明度;

    9、以版权文本显示中心坐标,用0x99ffffff颜色在新图像显示版权文本,颜色中的0x99为文本颜色不透明度;

    10、制作完毕。

    本例子综合运用了GDI+常用的图像操作过程和文本显示过程,包括图像显示属性对象和文本显示格式对象的运用。

    原C++ GDI+版本的Graphics.DrawString函数有个以x,y坐标为参数的重载方法,C版本将它删去了,只保留了以布局矩形为参数的方法,例子中的代码fRect = MakeRectF(phWidth / 2 , phHeight - 26, 0, 0);是建立布局矩形,其中的x,y参数为文本显示的中心点,而非文本显示的左上角坐标,这是因为例子中文本格式设置为居中显示(StrFormatSetAlignment(format, StringAlignmentCenter);),所以文本显示起始坐标点必须为文本中心点;而Width和Height参数分别设置为0,意思是不限制文本显示的右边和下边的边界,相当于原C++版本以x,y坐标为参数的重载方法,当文本长度超出时会截断,反之,如果给出具体的Width和Height,当文本长度超出时会换行。

    例子中也演示了如何保存图像,并给出了设置保存图像质量编码参数的代码(仅对jpeg格式图像有效)。保存图像时用到的GetEncoderClsid函数是原GDI+中没有的,为方便编写保存图像代码,我将该函数写在了GDI+头文件GdipImageCode_c.h中。如果没有设置保存图像编码参数,ImageSavexxxx系列函数中的encoderParams参数设置为NULL即可,但其中的clsidEncoder参数是必须的。

    例子代码使用的窗口框架代码和GDI+ C语言版本下载地址见《在C语言Windows应用程序中使用GDI+》。

    下面是例子运行界面图,其中左上为原始图片,左下为原始水印图片,右边是制作好的带版权印记的水印图片:

C语言版GDI+应用例子 -- 制作水印图片_第1张图片

    指导和建议请来信:[email protected][email protected]

 

你可能感兴趣的:(c,null,语言,button,GDI+,winapi)