首先,在StdAfx.h中静态调用diplus.lib,即由编译系统完成对DLL的加载,应用程序结束时卸载DLL的编码。如下

#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#include "GdiPlus.h"
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")
#endif

在类的头文件中定义,以下成员变量,用来初始化GDI+的使用和结束使用。

GdiplusStartupInput m_gdiplusStartupInput; 
ULONG_PTR m_gdiplusToken;

然后在OnCreate()函数中加入初始化GDI+的函数:

GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);

在OnDestroy()函数中加入结束GDI+使用的函数:
GdiplusShutdown(m_gdiplusToken);

定义转换函数:BOOL MBmpToMImage(CMemFile& cbfBmp, CMemFile& cbfImage, CString strType)

其中:
CMemFile& cbfBmp表示原位图文件;
CMemFile& cbfImage表示转换后的图形文件;
CString strType表示转换的图片类型。

该函数中主要的处理为以下几步:
        将原位图文件转换为IStream
         定义Image类实例,并使用第1步获得的IStream初始化
        获取转换的图片类型的CLSID
        将Image以转换的图片类型保存到IStream中
        将IStream转换为CMemFile内存文件(也可为CFile)
        详细代码如下:

BOOL MBmpToMImage(CMemFile& cbfBmp, CMemFile& cbfImage, CString strType)
{
int iBmpSize = cbfBmp.GetLength();
HGLOBAL hMemBmp = GlobalAlloc(GMEM_FIXED, iBmpSize);
if (hMemBmp == NULL) return FALSE;
IStream* pStmBmp = NULL;
CreateStreamOnHGlobal(hMemBmp, FALSE, &pStmBmp);
if (pStmBmp == NULL) 
{
   GlobalFree(hMemBmp);
   return FALSE;
}
BYTE* pbyBmp = (BYTE *)GlobalLock(hMemBmp);
cbfBmp.SeekToBegin();
cbfBmp.Read(pbyBmp, iBmpSize);

Image* imImage = NULL;
imImage = Image::FromStream(pStmBmp, FALSE);
if (imImage == NULL) 
{
   GlobalUnlock(hMemBmp);
   GlobalFree(hMemBmp);
   return FALSE;
}
USES_CONVERSION;
CLSID clImageClsid;
GetImageCLSID(A2W("image/"+strType.GetBuffer(0)), &clImageClsid);

HGLOBAL hMemImage = GlobalAlloc(GMEM_MOVEABLE, 0);
if (hMemImage == NULL)
{
   pStmBmp->Release();
   GlobalUnlock(hMemBmp);
   GlobalFree(hMemBmp);
   if (imImage != NULL) delete imImage;
   return FALSE;
}
IStream* pStmImage = NULL;
CreateStreamOnHGlobal(hMemImage, TRUE, &pStmImage);
if (pStmImage == NULL)
{
   pStmBmp->Release();
   GlobalUnlock(hMemBmp);
   GlobalFree(hMemBmp);
   GlobalFree(hMemImage);
   if (imImage != NULL) delete imImage
   return FALSE;

imImage->Save(pStmImage, &clJpgClsid);
if (pStmImage == NULL) 
{
   pStmBmp->Release();
   pStmImage>Release();
   GlobalUnlock(hMemBmp);
   GlobalFree(hMemBmp);
   GlobalFree(hMemImage;
   if (imImage != NULL) delete imImage;
   return FALSE;
}
LARGE_INTEGER liBegin = {0};
pStmImage->Seek(liBegin, STREAM_SEEK_SET, NULL);
BYTE* pbyImage = (BYTE *)GlobalLock(hMemImage);
cbfImage.SeekToBegin();
cbfImage.Write(pbyImage, GlobalSize(hMemImage));

if (imImage != NULL) delete imImage;
pStmBmp->Release();
pStmImage->Release();
GlobalUnlock(hMemBmp);
GlobalUnlock(hMemImage);
GlobalFree(hMemBmp);
GlobalFree(hMemImage);
return TRUE;
}

IStream是COM中的接口,真是搞不懂这样也可以~~~

转载于:https://www.cnblogs.com/myitm/archive/2011/08/19/2145437.html

使用IStream和GDI+在内存中实现图像格式转换相关推荐

  1. 【工具篇】float值在不同系统内存中的数值转换工具

    一.原理 float在内存中如何存储? float为浮点型,32位机器中占4字节共32bit,下标0-31. 31 位:符号位,正数为0,负数为1. 30 位:方向位.小数点左移位1,右移为0. 23 ...

  2. C++由(int)a引发的思考及浮点数在内存中的表示

    [转自:http://blog.csdn.net/borefo/article/details/4620964] 今天看到一段代码,如下:请写出它的输出结果 #include<iostream& ...

  3. VB6 在内存中生成bitmap图像,并将其保存为byte()数组

    在VB6内存中创建bitmap图像,并将其保存为byte()数组 在项目中添加一个模块,用于封装GDIPlus函数 下载地址: gdiplus函数封装 从内存中创建相应的信息 '全局声明 Dim to ...

  4. win7(旗舰版)下,OleLoadPicture 加载内存中的图片(MagickGetImageBlob),返回值 0

    昨天去三哥家,想把拍好的照片缩小一下,我用很久前写的一个软件进行缩小,然后进行一次效果预览,这个时候弹出: Call OleLoadPicture Fail - loadPictureFromMW 奇 ...

  5. 内存中绘图 Memdc

    内存中绘图 Memdc CDC MemDC;   //首先定义一个显示设备对象,所有的绘制首先绘制到这块内存中 CBitmap MemBitmap; //定义一个位图对象 //随后建立与屏幕显示兼容的 ...

  6. 如何显示内存中的 HTML 网页

    一.如何显示内存中的 HTML 网页 或者因为网页保密的考虑:或者因为软件分发的考虑,有的时候就需要让 IE 或 IE 浏览器控件显示内存或资源中的 HTML 网页.在 MFC 中,CHtmlView ...

  7. Win32编程之从内存中加载位图,并显示到hdc上

    近期在项目中遇到一个问题,如何在实现从内存中加载RBG帧数据,然后提交到hdc上显示,这里假设大家对win32程序已经很熟了,有了相关的框架,如果不熟的小伙伴可以看我的老师编写的一本书<游戏程序 ...

  8. python slice是共享内存吗_在共享内存中使用numpy数组进行多处理

    在共享内存中使用numpy数组进行多处理 我希望在共享内存中使用numpy数组,以便与多处理模块一起使用.困难之处在于它像一个numpy数组一样使用,而不仅仅是作为一个ctype数组使用.from m ...

  9. 整数中内存中的保存方式:大端、小端

    一个数在计算机内存中的保存方式是大端法表示还是小端法表示? 首先C++当中并没有规定我们这个内存中,整数在内存中是采用大端法还是小端法表示.所以在编写程序的时候这一点并不是很重要. 但是如果编写一个程 ...

  10. C:内存中供用户使用的存储空间

    内存中供用户使用的存储空间可分为: 代码区:存代码的地方. 常量区:存常量的地方. 静态存储区:存变量的地方. 动态存储区:存变量的地方. 存变量的分为静态存储和动态存储两个区: "静态&q ...

最新文章

  1. 藏獒当初为何成为“神话”,如今是谁毁了昔日藏獒的神话?
  2. 安装mysql.dox_linux虚拟机上装mysql数据库-Go语言中文社区
  3. [算法笔记]-环形链表Ⅱ-解题方法
  4. DHL:jQuery框架学习使用总结,插件,继续中...
  5. python实现编译器链接器_Python入门之Python编译器
  6. 也谈设计模式,实例票据打印 解析 Decorator
  7. 山东财经大学燕山学院计算机王栋,选修课Photoshop王栋的群谁有
  8. 10010序列检测器的三段式状态机实现(verilog)
  9. 重庆大学计算机学院期刊范围,重庆大学期刊目录.doc
  10. android 屏幕坐标系,android 屏幕坐标总结
  11. 拍拍贷第三届“魔镜杯”启动 :10万美金邀你“秀出你的算法!”
  12. 服务器自定义镜像,vs2010 使用自定义服务器
  13. android手机传感器,安卓手机传感器
  14. 使用PPT保存300dpi或者指定dpi的高质量图片
  15. 【机器学习7】决策树
  16. 基于spring boot的毕业设计论文选题申报管理系统
  17. Mysql基础入门篇(二)
  18. linux id / chown 命令 nobody uid gid 是什么
  19. 【算法理论】bin packing 装箱问题
  20. DHU Deep Learning Practice_章节测验【1】

热门文章

  1. RocketMQ Client 编码快速入门 与 可视化控制台
  2. Wait 线程阻塞 与 Notify、NotifyAll 线程唤醒
  3. cacti linux io,【cacti】Linux磁盘I/O监控
  4. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_09 序列化流_6_练习_序列化集合...
  5. 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第2节 线程实现方式_13_Thread和Runnable的区别...
  6. LeetCode Student Attendance Record I
  7. 4.2 set和multiset
  8. PHP报错: Can't use method return value in write context
  9. 【转】PP模块快速入门之功能简介
  10. 为什么调用支付宝接口后返回是错误页面!