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

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

Call OleLoadPicture Fail - loadPictureFromMW

奇怪,这个图片批量处理软件我一直在用,在 xp系统下从来没出现过这样的提示,为什么在 win7下无法正常进行图片的效果预览?

更让我接受不了的是,从来没有用户或朋友向我反应这个问题,难道他们都不用 win7?

今天下午问了一个朋友借了台win7的笔记本,通过一下午的测试,解决了这个问题。

之前的代码思路:

通过 PBYTE pData =MagickGetImageBlob(MagickWand *, size_t length) 获取一张图片在内存中的指针和长度。

if(CreateStreamOnHGlobal(pData, FALSE, &pstream) == S_OK) //将字节数组转换成 IStream*
 {       
        if(SUCCEEDED(OleLoadPicture(pstream, length, TRUE, &IID_IPicture, (void**)&pPic)))

这个代码在 xp下运行一切正常,可以正常加载 pData 指向的图片数据。

但在 win7奇旗舰版下, OleLoadPicture(....) 返回值 < 0

搞了2个小时也没找到解决办法,这个时候我想起 OleLoadPicture 加载文件的时候先根据文件大小分配一个内存空间,然后加载文件到指定的内存空间:

HANDLE FileHandle;
    ULONG SizeH, SizeL, ReadCount;
    IStream *pstream = NULL;
    //IPicture *pPic = NULL;
   
    FileHandle = CreateFile(pFilePath,
                            GENERIC_READ,
                            FILE_SHARE_READ,
                            NULL,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL, NULL
                           );
   
    if(FileHandle == INVALID_HANDLE_VALUE)
        return;
   
    SizeL = GetFileSize(FileHandle, &SizeH);
   
    HGLOBAL pBuffer = GlobalAlloc(GMEM_MOVEABLE, SizeL);
   
    if(pBuffer == NULL)
    {
        CloseHandle(FileHandle);
        return;
    }
   
    LPVOID pDes = GlobalLock(pBuffer);
   
    if(ReadFile(FileHandle, pDes, SizeL, &ReadCount, NULL) == 0)
    {
        GlobalUnlock(pBuffer);
        CloseHandle(FileHandle);
   
        GlobalFree(pBuffer); //释放全局内存
   
        return;
    }
   
    GlobalUnlock(pBuffer);
    CloseHandle(FileHandle);
   
    if(CreateStreamOnHGlobal(pBuffer, TRUE, &pstream) != S_OK)
    {
        GlobalFree(pBuffer); //释放全局内存
        return;
    }
   
    if(SUCCEEDED(OleLoadPicture(pstream, SizeL, TRUE, &IID_IPicture, (void**)&pPic)))
    {

由于 pData是通过MagickGetImageBlob()获取的图片数据指针, 会不会是 OleLoadPicture 无法加载指向 pData的图片数据呢?

我就按照 OleLoadPicture 加载图片文件的方式,先根据图片大小(length)分配一个内存空间,然后使用 memcpy 将指向 pData的数据复制一份到 pBuffer中,然后使用 OleLoadPicture 加载 pBuffer的图片数据,这样竟然解决了在win7下的问题:

size_t length;
    PBYTE pData = MagickGetImageBlob(mw, &length); //从mw中读取完整的字节数组
  
    //printf("length:%d\n",length);
  
    //测试发现在 [windows 7旗舰版], CreateStreamOnHGlobal & OleLoadPicture 无法直接使用 pData,
    //经过各种尝试后,发现,可以申请一个临时的内存空间(pBuffer), 将 PData 复制一份到这个内存空间:pBuffer
    //然后使用 CreateStreamOnHGlobal & OleLoadPicture 处理 pBuffer 而不是 PData
  
    HGLOBAL pBuffer = GlobalAlloc(GMEM_MOVEABLE, length); //开辟一个内存空间
    LPVOID pDes = GlobalLock(pBuffer); //锁定内存空间
    memcpy(pDes,pData,length); //将 pData 的内容复制一份到 pBuffer
    GlobalUnlock(pBuffer); //解锁内存空间
  
    IStream *pstream = NULL;
  
    if(CreateStreamOnHGlobal(pBuffer, FALSE, &pstream) == S_OK) //将字节数组转换成 IStream*
    {
        if(SUCCEEDED(OleLoadPicture(pstream, length, TRUE, &IID_IPicture, (void**)&pPic)))

2013-06-03

时间: 2024-11-03 22:02:00

win7(旗舰版)下,OleLoadPicture 加载内存中的图片(MagickGetImageBlob),返回值 < 0的相关文章

C#加载网页中的图片

需求:在winform程序中加载网页中的验证码 1.打开网页,获取到网页中img的src属性,得到的是图片的base64编码字符串: string base64string= webBrowser1.Document.All["yzm_img"].GetAttribute("src"); 2.将字符串转换为图片: byte[] b = Convert.FromBase64String(base64string); MemoryStream ms = new Memo

使用MFC CImage类和GDI+ Image加载并绘制PNG图片

一.使用MFC CImage类加载PNG图片        为了测试CImage绘制PNG图片的效果,我们用截图软件截得一张360的界面,然后使用PhotoShop等工具在图片的周边加上了透明的区域,然后保存成PNG图片文件.CImage首先从文件中加载,即 CImage* m_pImgBk; ...... m_pImgBk = new CImage; m_pImgBk->Load( _T("res\\bk.png")); if ( m_pImgBk->IsNull() )

weex 加载 .xcassets 中的图片资源

背景 因为 .xcassets 中的图片资源只能通过 imageNamed: 方法加载,所以需要做一些特殊处理,才能提供给 Weex 使用(PS:纯属娱乐,因为 Weex 跨平台的特性,这种针对某一端做实现的方案实用价值并不大). 方案 观察 WeexSDK 发现有 WXImgLoaderProtocol 这个协议,这个协议包含了下面的方法: - (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFr

IT忍者神龟之如何批量删除Win7旗舰版系统下的.svn文件

在使用SVN工具的时候会生成一些以"svn"作为后缀的文件,而且每个文件夹下都有,数量很多的. 如果想删除Win7旗舰版系统下的.svn文件夹,通过手动删除的渠道是最麻烦的,因为每个文件夹下面都存在这样的文件. 在记事本输入以下代码并命名为以.reg作为扩展名的文件: Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN] @="Dele

联想电脑win7旗舰版环境下的如何成功配置AppServ

毕业设计中需要用Mysql数据库,并且想找一个方便Mysql数据库编程的开发工具,百度搜索了一下,AppServ集成环境安装包能快速搭建环境. 安装过程比较简单 一.下载安装包,我下载的是AppServ 2.5.10 for Windows,推荐大家到appserv 官方网站  http://www.appservnetwork.com/  下载安装包 二.点击安装程序,按照提示一路安装下去 注意: 1.Apache HTTP service PHP运行环境(必选项) 3. MYSQL data

Win7旗舰版64位下编译32位的带CGO的GoLang程序

开发过程中,遇到一个问题. 客户服务器端为32位Windows系统,软件系统必须编译成32位系统才能在客户端正常运行. 本人开发环境: Win7旗舰版64位 Golang 1.8 64位 TMD-GCC5.1 64位 在此情况下,使用批处理文件如下: set GOOS=windows set GOARCH=386 set CGO_ENABLED=1 go build pcms pause 系统调用go-sqlite3,使用cgo调用,会报出编译错误,原因就是gcc调用的异常 使用交叉编译的方式总

通用版的上拉刷新下拉加载控件

通用版的上拉刷新下拉加载控件 适用于各种控件实现上拉刷新,下拉加载的功能. 下载地址:http://www.devstore.cn/code/info/964.html 运行截图:    

【转载】Oracle 11g R2 for Win7旗舰版(64位)- 安装

免责声明:     本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除.     原文作者:bluepoint2009      原文地址:http://www.cnblogs.com/bluepoint2009/p/oracle-11g-R2-win7-64bit.html 1.下载Oracle 11g R2 for Windows的版本                                    下载地址:http://www.oracle.com/t

Oracle 11g R2 for Win7旗舰版(64位)的安装步骤

数据库有好多版本,我应该学习哪个? 万物一理,数据库的版本虽然多,本质是一样的,变化的只是表象,你是oracle7的专家,一定也是oracle11g的专家.Oracle数据库越来越受欢迎,下面介绍一下Oracle 11g R2 for Win7旗舰版(64位)的安装步骤: 1. 下载Oracle 11g R2 for Windows的版本 下载地址:http://www.oracle.com/technetwork/database/enterprise-edition/downloads/in