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

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

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

  1. Universal-Image-Loader解析(三)——用ListView和ViewPager加载网络中的图片

           现在我们终于可以通过这个框架来实现ListView中加载图片了,至于ViewPager还是别的,原理其实都是一样的 一.ListView 1.布局文件 list_layout.xml & ...

  2. 如何在64位WIN7旗舰版下安装SQL2000

    1>找到安装包下面的“DEVELOPER”或“ENTERPRISE”等下的X86\SETUP下的“SETUPSQL.EXE”,在安装前右键单击这个文 件, 1.1 打开“兼容性”标签,兼容模式选 ...

  3. win7旗舰版下配置IIS服务器

    选择上述的插件后,Windows 需要更新一段时间,并重启电脑 测试是否安装成功:http://localhost       注意:默认端口号是 80,不能和tomcat 的 80 端口同时重启 常 ...

  4. Glide 4.0.0 下之加载本地缓存的图片

    在网上搜了下,无意中发现RequestOptions还有个方法: onlyRetrieveFromCache 用了下是OK的 try { File imageFile = Glide.with(con ...

  5. iOS:延迟加载和上拉刷新/下拉加载的实现

    lazy懒加载(延迟加载)UITableView 举个例子,当我们在用网易新闻App时,看着那么多的新闻,并不是所有的都是我们感兴趣的,有的时候我们只是很快的滑过,想要快速的略过不喜欢的内容,但是只要 ...

  6. [Android] Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.LoaderCallbacks)

    Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.Lo ...

  7. 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值---部分内容可能不确切,待讨论

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回值  ...

  8. win7 32位支持多大内存|win7 32位旗舰版最多能识别多少内存

    win7 32位支持多大内存|win7 32位旗舰版最多能识别多少内存 内存的大小决定系统运行速度,所以不少人认为只要内存加大就行了,其实这是不对的,因为win7 32位能支持的内存大小是有限制的,并 ...

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

    联想电脑win7旗舰版环境下的如何成功配置AppServ 毕业设计中需要用Mysql数据库,并且想找一个方便Mysql数据库编程的开发工具,百度搜索了一下,AppServ集成环境安装包能快速搭建环境. ...

随机推荐

  1. Redis Cluster日常操作命令梳理

    在之前的一篇文章已经介绍了Redis Cluster及其部署,下面说下Redis Cluster日常操作命令: 一.以下命令是Redis Cluster集群所独有的,执行下面命令需要先登录redis: ...

  2. C_数据结构_递归不同函数间调用

    # include <stdio.h> void f(); void g(); void k(); void f() { printf("FFFF\n"); g(); ...

  3. 树的最长链-POJ 1985 树的直径(最长链)+牛客小白月赛6-桃花

    求树直径的方法在此转载一下大佬们的分析: 可以随便选择一个点开始进行bfs或者dfs,从而找到离该点最远的那个点(可以证明,离树上任意一点最远的点一定是树的某条直径的两端点之一:树的直径:树上的最长简 ...

  4. 回顾:前端模块化和AMD、CMD规范(全)

    先列举下一些著名言论: "我想定义一个 each 方法遍历对象,但页头的 util.js 里已经定义了一个,我的只能叫 eachObject 了,好无奈." "Requi ...

  5. Vuex实现原理解析

    我们在使用Vue.js开发复杂的应用时,经常会遇到多个组件共享同一个状态,亦或是多个组件会去更新同一个状态,在应用代码量较少的时候,我们可以组件间通信去维护修改数据,或者是通过事件总线来进行数据的传递 ...

  6. mooc linux学习总结

    通过八周的学习获得了很多知识.       首先,通过网课老师形象生动的讲述和描述一些专业词汇,使我更加深刻的记住并掌握了这些内容:动态的展示堆栈的变化,更容易理解一段汇编代码:分析操作系统的工作,记 ...

  7. Linux内核设计第十七章笔记

    第十七章 设备与模块 关于设备驱动和设备管理,四种内核成分 设备类型:在所有unix系统中为了统一普通设备的操作所采用的分类 模块:Linux内核中用于按需加载和卸载目标代码的机制 内核对象:内核数据 ...

  8. GCP试用到期再申请

    目标 GCP的免费试用到期了.网传可以续用,看了教程,记录下来. 法一 应该可以直接用一个新gmail账号的.这个方法的难点可能在于注册新账号有门槛.我有一个很久以前注册过的,试着找回了密码,登入GC ...

  9. Spring Cloud 路由网关服务端

    修改application.properties配置文件:服务端口号.本机名称: 启动注册中心:java -jar uap-register-server-1.0.jar --spring.confi ...

  10. Netty4ClientHttpRequest代码赏析

    private static int getPort(URI uri) { int port = uri.getPort(); if (port == -1) { if ("http&quo ...