当前位置:硬件测评 > vs2010限制图片上传格式_开源JPEG图片(解)压缩库libjpeg的编译及使用示例(以VS2010为例)

vs2010限制图片上传格式_开源JPEG图片(解)压缩库libjpeg的编译及使用示例(以VS2010为例)

  • 发布:2023-10-01 08:40

文章目录

GDI和GDI+GDIplus的介绍和使用介绍GDI+库,使用GDI+读取图像文件

获取显示区域绘图句柄hdc创建GDI+绘图对象,并通过GDI+绘图对象的`DrawImag`方法显示图像。关闭GDI+最简单示例代码(25行)

GDI 和 GDI+

GDI是Graphics Device Interface的缩写,意为图形设备接口。它的主要任务是负责系统与绘图程序之间的信息交换以及处理所有Windows程序的图形输出。利用GDI提供的众多功能,您可以轻松地在屏幕、打印机和其他输出设备上输出图形、文本等操作。 GDI使程序员能够将应用程序的输出转换为硬件设备的输出,而不必担心硬件设备和设备驱动程序。实现了程序开发人员与硬件设备的隔离,极大的方便了开发工作。

GDI+(Graphics Device Interface plus)是windows 2000年后开发的新技术。GDI+是一组通过C++类实现的应用程序编程接口。 GDI+ 是以前版本的 GDI 的继承者。出于兼容性原因,Windows XP 仍然支持以前版本的 GDI。然而,在开发新的应用程序时,开发人员应该使用GDI+来满足图形输出需求,因为GDI+与以前的Windows版本不兼容。 GDI在此版本中进行了优化,并添加了许多新功能。

作为图形设备接口,GDI+允许应用程序开发人员输出屏幕和打印机信息,而无需考虑特定显示设备的细节。它们只需要调用GDI+库输出的类的一些方法即可完成图形操作。确实通过这些方法将绘图工作交给了具体的设备驱动程序。 GDI+ 将图形硬件和应用程序相互隔离。这使得开发人员可以非常轻松地编写与设备无关的应用程序。

VC++6.0,诞生于1998年,支持GDI编程。但默认情况下不支持 GDI+。用户需要安装新的Windows SDK。不过VC 2010版本直接支持GDI+编程。

GDI仅支持读取bmp等少数图像格式,而GID+支持大多数常见图像格式(如jpg、png、tif、gif等)。为了方便多种格式图像文件的读取和显示,下面实验以VS2010为开发平台,讲解如何使用GDI+读取图像文件并在控制台窗口中显示。 (关于如何使用MFC在新窗口或对话框窗口中应用GDI+的文章有很多,本文不再赘述)。

【注】VS2010绿色版请参见:VS2010绿色版下载

GDIplus介绍及使用

GDI+ 库简介

要使用GDI+,您需要导入gdiplus.h并链接到gdiplus.lib库。 GDI+ 函数位于命名空间 Gdiplus 中,也必须使用 using namespace Gdiplus; 来引入。否则,需要在GDI+函数前添加Gdiplus::前缀。

#包括

#pragma comment(lib,"gdiplus.lib")

//#define ULONG_PTR ULONG

使用命名空间Gdiplus;

【注】:在VC6中编译时,如果ULONG_PTR ULONG未定义,可以添加

#define ULONG_PTR ULONG

因为GDI+是WIndows Platform SDK的一部分,而不是MFC的一部分,并且SDK中ULONG_PTR的定义与MFC中的定义冲突,所以出现这个问题。

使用GDI+读取图像文件

然后,在主程序中使用GdiplusStartup函数启动GDI+:

GdiplusStartupInput m_gdiplusStartupInput;

ULONG_PTR m_gdiplusToken;

GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);

通过FromFile打开图像文件。

Image* pImage = Image::FromFile(L"wtclablogo.png");

也可以这样:

Image* pImage = new Image(L"testfile.jpg");

其中L"testfile.jpg"将字符串转换为宽字符。因为Image类只接受宽字符串WCHAR。

【注】以下函数也可用于将字符串 char * 转换为宽字符串类型 WCHAR。

WCHAR * charToWCHAR(char *s) {

int w_nlen = MultiByteToWideChar(CP_ACP, 0, s, -1, NULL, 0);

WCHAR *ret;

ret = (WCHAR*)malloc(sizeof(WCHAR)*w_nlen);

memset(ret, 0, sizeof(ret));

MultiByteToWideChar(CP_ACP, 0, s, -1, ret, w_nlen);

返回ret;

}

例如,要从main函数的命令行参数(argv[1]中设置)读取文件名,需要进行以下转换:

WCHAR * 文件名;

文件名 =charToWCHAR(argv[1]);

图像* pImage = 新图像(文件名);

获取显示区域绘图句柄hdc

extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();

主(){

HWND hWnd = GetConsoleWindow();

HDC hdc = GetDC(hWnd);

}

创建 GDI+ 绘图对象

构造Graphics对象并将其绑定到显示区域hdc。 (这里没有使用双缓冲)

图形图形(hdc);

通过GDI+绘图对象的DrawImag方法显示图像

最后通过Graphics对象的DrawImage方法在屏幕上进行绘制。其中,使用pImage->GetWidth()和pImage->GetHeight()来获取图像的宽度和高度(像素数)。

graphics.DrawImage(pImage, 0, 0, pImage->GetWidth(), pImage->GetHeight());

关闭GDI+

可以在程序执行结束时关闭GDI+(在控制台窗口程序中,可以不关闭而退出)

GdiplusShutdown( m_gdiplusToken );

最简单的示例代码(25行)

本例读取一张png图片,放大2倍后显示。

#包括

#包括

#包括

#pragma comment(lib,"gdiplus.lib")

extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();

使用命名空间Gdiplus;

int main() {

Gdiplus::GdiplusStartupInput m_gdiplusStartupInput;

ULONG_PTR m_gdiplusToken;

GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);

HWND hWnd = GetConsoleWindow();

HDC hdc = GetDC(hWnd);

图像* pImage = Image::FromFile(L"wtclablogo.png");

if ((pImage==NULL)||(pImage->GetLastStatus()!=Ok))

{

如果(pImage)

{

printf("无法打开图片");

删除pImage;

pImage = NULL;

}

返回FALSE;

}

图形图形(hdc);

graphics.DrawImage(pImage, 0, 0, pImage->GetWidth()*2, pImage->GetHeight()*2);

返回0;

}

以上代码可以在VS2010和VC++6(辅以GDI+)集成环境下编译。运行结果如下:

从运行结果来看,wtclablogo.png图片的透明部分也能正确显示。

【注】对于gif格式等多帧组成的图像,VS2010版本自带的GDI+只能支持帧分析。因此,下面读取gif图像的实验必须在VS2010中编译。

为了图像显示后能够重绘刷新,可以使用while循环(Ctrl+C退出)结合Sleep函数来实现,如上一篇文档所述。

同时(正确){

graphics.DrawImage(pImage, 0, 0, pImage->GetWidth()*2, pImage->GetHeight()*2);

睡眠(100);

}

完整代码:

#包括

#包括

#包括

#pragma comment(lib,"gdiplus.lib")

extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();

使用命名空间Gdiplus;

int main() {

Gdiplus::GdiplusStartupInput m_gdiplusStartupInput;

ULONG_PTR m_gdiplusToken;

GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);

HWND hWnd = GetConsoleWindow();

HDC hdc = GetDC(hWnd);

图像* pImage = Image::FromFile(L"wtclablogo.png");

if (!pImage) {

printf("无法打开图片");

返回-1;

}

图形图形(hdc);

同时(正确){

graphics.DrawImage(pImage, 0, 0, pImage->GetWidth()*2, pImage->GetHeight()*2);

睡眠(100);

}

GdiplusShutdown( m_gdiplusToken );//关闭GDI+,可略此句

返回0;

}

首先解释以下两个名词(仅供参考,可跳过)

JPEG=联合摄影专家组(Joint Photographic Experts Group),是第一个国际图像压缩标准。 JPEG图像压缩算法不仅能够提供良好的压缩性能,而且具有较好的重建质量,广泛应用于图像和视频处理领域。人们日常遇到的.jpeg、.jpg等是指图像数据经过压缩编码后在介质上的存储形式,不能与JPEG压缩标准混淆。 (百度百科)

IJG 是一个非正式小组,编写并分发广泛使用的免费 JPEG 图像压缩库。第一个版本于 1991 年 10 月 7 日发布。 (http://www.sychzs.cn/)

本文将重点介绍IJG提供的JPEG图像压缩/解压缩库的编译和初步使用。

首先从IJG网站http://www.sychzs.cn/下载源代码。编辑本文时发布的版本是版本 9a

编译

我们要在Visual Studio 2010环境下编译,编译目标是libjpeg.lib

1。下载www.sychzs.cn并解压

2。将 www.sychzs.cn 文件的内容复制到新文件 jconfig.h

3。编辑www.sychzs.cn文件的内容

由于机器配置等原因,.mak文件路径可能会有所不同

? ? ?

以上截图为测试机上的文件路径(Windows 7 Professional 64位)

C:\ Program Files(x86)\ Microsoft SDKs \ Windows \ v7.0A \ Include \ Win32.Mak

4。编译

开始菜单-->VS2010工具-->VS命令提示符

切换到源码所在目录

键入命令 nmake /f www.sychzs.cn nodebug=1

nodebug开关(=1打开)表示以release模式编译

几秒后,编译完成

生成的目标是libjpeg.lib

5。使用

复制以下4个文件

其中jconfig.h是第2步修改的,jmorecfg.h是一些更详细的配置,jpeglib.h是库引用语句

使用时只需将上述头文件和库文件添加到工程中即可。

示例

以下是一个简单的JPEG文件读取(解压)示例

#包括

#include "jpeglib.h"

#pragma comment(lib,"libjpeg.lib")

#pragma warning(disable:4996)

typedef 无符号字符 BYTE;

int main(void)

{

printf("输入jpeg文件路径:");

char szFileName[256] = { 0 };

scanf("%s", szFileName);

jpeg_decompress_struct cinfo;

jpeg_error_mgr jerr;

// 第 1 步:标准错误

cinfo.err = jpeg_std_error(&jerr);

// 第 2 步:创建

jpeg_create_decompress(&cinfo);

文件* pf = fopen(szFileName, "rb");

if (pf != NULL)

{

// 第三步:IO

jpeg_stdio_src(&cinfo, pf);

// 第 4 步:标题

jpeg_read_header(&cinfo, TRUE);

长字节 = cinfo.image_width*cinfo.image_height*cinfo.num_components;

printf("分配%d字节内存:",bytes);

BYTE* 数据 = 新 BYTE[字节];

if(数据!= NULL)

{

printf("好的。\n准备解压图片...\n");

// 第 5 步:开始

jpeg_start_decompress(&cinfo);

JSAMPROW row_pointer[1];

// 第 6 步:读取扫描

while (cinfo.output_scanline < cinfo.output_height)

{

row_pointer[0] = &data[(cinfo.output_height - cinfo.output_scanline - 1)*cinfo.image_width*cinfo.num_components];

jpeg_read_scanlines(&cinfo, row_pointer, 1);

}

// 第 7 步:完成

jpeg_finish_decompress(&cinfo);

// 用

做某事

// 这里是字节数据[]

//然后松开

删除[]数据;

}

其他

{

printf("失败。\n");

}

// 第 8 步:摧毁

jpeg_destroy_decompress(&cinfo);

fclose(pf);

printf("JPEG解压完成。\n");

}

其他

{

printf("无法打开\'%s\'\n", szFileName);

}

printf("按 ENTER 继续...");

getchar();

getchar();

返回0;

}

某次运行结果截图(拍摄了1920*1080 JPG格式图片进行测试)

原创文章、博文地址

http://www.sychzs.cn/fengyhack/article/details/42239807

转载于:https://www.sychzs.cn/fengyhack/p/10603586.html

今天的测试程序需要简单的按钮图片加载,并且图片是在VS之外编辑和替换的。第一次编译时出现错误。

这种错误很少见。

我尝试修改原始图像,例如更改格式、更改位图深度等,但没有成功。

直接从其他地方复制新镜像覆盖,然后用VS重新导入资源即可解决问题。

?

相关文章