Gdiplus::Image::FromFile(..)无法读入文件?

ghost129 2009-02-28 04:08:27
我的代码如下:
int __fastcall CTestDlg::SetTransparent(LPWSTR lpSkinFile, int nTran)
{
int Width,Height;
m_Image=Gdiplus::Image::FromFile(lpSkinFile); // Use GDI+ load image
Width = m_Image->GetWidth();
Height = m_Image->GetHeight();
...
}
一到这里就显示: "Unhandled exception in Test.exe:0xc0000005:Access exception."

其中lpSkinFile的值用SetTransparent(L"F:\\Test\\Debug\\a.png", 100);传递的,我加入断点后调试,发现m_Image在之前的值是0xcccccccc,执行到 m_Image=Gdiplus::Image::FromFile(lpSkinFile);后就变为0x00000000; 后来我试图从流中读取,代码如下:
void CTestDlg::InitialImage(LPWSTR path , Image *image)
{
char name[MAX_PATH];
WideCharToMultiByte(CP_UTF8,0,path,-1,name,strlen(name),0,0);

CFile file;
try
{
file.Open (path,CFile::modeRead|CFile::typeBinary);
}
catch(CFileException *p)
{
p->ReportError();
return;
}
DWORD len = file.GetLength ();// 申请全局空间
HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, len);
BYTE* pmem = (BYTE*)GlobalLock(hMem);
file.ReadHuge (pmem,len);// 从文件读出来。
IN IStream* pstm;
CreateStreamOnHGlobal(hMem,FALSE,&pstm);
image=Gdiplus::Bitmap::FromStream(pstm);// 从流加载
GlobalUnlock(hMem);
GlobalFree(hMem);
pstm->Release();
file.Close ();
}
我把m_Image=Gdiplus::Image::FromFile(lpSkinFile);换为m_Image=InitialImage(lpSkinFile,m_Image);发现和上面的问题一样;再后来,我用Bitmap类代替Image类发现还是不行,为什么呢? 请问这样问题如何解决,大家帮帮忙啊,谢谢了!
...全文
2407 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhaojianzhong001 2012-10-15
  • 打赏
  • 举报
回复
liuquancai1,正解
aaaa9813 2011-08-31
  • 打赏
  • 举报
回复
楼主不厚道,自己成功了,就不管后来人了,多亏了GdiPlusInit把答案贴出来,万分感谢
奶油小生 2011-07-25
  • 打赏
  • 举报
回复
神啊~我一路看下来,原来是这个原因,浪费哥的时间 啊~
全才欧巴 2010-11-30
  • 打赏
  • 举报
回复
要在初始化对话框的地方初始化GDI+ :

Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;

//初始化GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
头文件包含:
#include <GdiPlusInit.h>
snowshlat2008 2010-07-15
  • 打赏
  • 举报
回复
麻烦解决了把原因给贴出来,我也遇到同样的问题了。
zhuangx 2010-06-16
  • 打赏
  • 举报
回复
求具体原因
agang200008 2009-09-02
  • 打赏
  • 举报
回复
我也遇到了,感谢说说原因嘛。
Soucula 2009-05-05
  • 打赏
  • 举报
回复
晕倒,解决了也要把原因贴出来嘛,帮助别人啊,我也遇到同样问题了
ghost129 2009-03-07
  • 打赏
  • 举报
回复
感谢Mackz的帮忙,也谢谢大家了,问题已经在Mackz的帮助下解决了!
菜牛 2009-03-05
  • 打赏
  • 举报
回复
发给我看看:mackz@sina.com
ghost129 2009-03-04
  • 打赏
  • 举报
回复
大家帮帮忙看一下,谢谢大家了! 自己先顶一下!
菜牛 2009-03-03
  • 打赏
  • 举报
回复
根据你的问题,你先把第一个函数(FromFile)用对了再说;至于后面的问题,把void CTestDlg::InitialImage(LPWSTR path , Image *image)改成void CTestDlg::InitialImage(LPWSTR path , Image *&image),否则函数内部对image参数的修改是不会返回给调用方的;或者修改函数返回类型,向你这样,m_Image=InitialImage(lpSkinFile,m_Image);参数中的m_Image不被修改,返回值是void,你说会怎么样?
ghost129 2009-03-03
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 Mackz 的回复:]
根据你的问题,你先把第一个函数(FromFile)用对了再说;至于后面的问题,把void CTestDlg::InitialImage(LPWSTR path , Image *image)改成void CTestDlg::InitialImage(LPWSTR path , Image *&image),否则函数内部对image参数的修改是不会返回给调用方的;或者修改函数返回类型,向你这样,m_Image=InitialImage(lpSkinFile,m_Image);参数中的m_Image不被修改,返回值是void,你说会怎么样?
[/Quote]

Mackz,谢谢你一直对本帖关注!感激涕零! ") 谢了!
按照你所说的,我很留心返回值和Image的引用指针问题,因为之前我一直认为参数是指针嘛,可以直接回传值.现在情况好转了一点:InitialImage()和ImageFromIDResource()都没有问题,因为我在SDI中已经让图像显示出来了,但我踪调试发现第一次m_image还是为0的(虽然图可以显示),直到以后才不为0,反复思考不得其解!但这说明了这不是函数的问题,但在基于Dialog中还是不行,那又是哪儿呢?不会是graphics的初始化吧,但和m_image的值没关系啊?我简直弄得精疲力尽了,请指教!

为了方便交流,我已把代码放邮箱中了,希望大家不厌其烦,谢了.
地址:just-do-it-now@163.com
密码:20080303
菜牛 2009-03-02
  • 打赏
  • 举报
回复
GDI+能处理png没错,但是你的文件名和路径可能有错啊。
ghost129 2009-03-02
  • 打赏
  • 举报
回复
Sorry! path是我发贴的时候写错了,误导大家了,不好意思, :)
改为name后还是无济于事! 断点调试时文件句柄hFile, 文件长度len, 内存地址hMem,pmem, 流指针pstm都有名自的值,不为空. 惟有image在执行后由0xcccccccc变为0x00000000,真是搞不懂.文件路径我又检查了N遍, 换了N个地方,都没有结果.我又退了一步:将图载入资源,再找到它,用LoadResource载入内存后用memcopy作为流(代码如下),还是不行,我所有的工作都没法进行了,大家帮帮忙啊,谢谢大家了!!!
BOOL CTestDlg::ImageFromIDResource(UINT nRsrcID, LPCTSTR pszType,Image * &pImage)
{
HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nRsrcID),pszType);
if (!hRsrc)
return FALSE;

DWORD dwLen = SizeofResource(hInst, hRsrc);// load resource into memory
BYTE* btRsrc = (BYTE*)LoadResource(hInst, hRsrc);
if (!btRsrc)
return FALSE;

HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, dwLen);// Allocate global memory on which to create stream

BYTE* btMem = (BYTE*)GlobalLock(hMem);
memcpy(btMem,btRsrc,dwLen);
IStream* pStream;
CreateStreamOnHGlobal(hMem,FALSE,&pStream);

pImage=Gdiplus::Image::FromStream(pStream);// load from stream

GlobalUnlock(hMem);// free/release stuff

pStream->Release();
FreeResource(btRsrc);

}


谢谢大家了!!!
alfwolf 2009-03-02
  • 打赏
  • 举报
回复
应该是你的文件路径的问题,导致加载文件失败,而你又不加判断得使用了指针m_Image
windtalker_neo 2009-03-02
  • 打赏
  • 举报
回复
感觉WideCharToMultiByte(CP_UTF8,0,path,-1,name,strlen(name),0,0); 这个函数在做WCHAR*转换path字符的时候出错,所以后面你open的时候文件名就出错了。
菜牛 2009-03-01
  • 打赏
  • 举报
回复
也许文件名无效或者不是可识别的图形。可以看一下GDIPlus的状态值。
ghost129 2009-03-01
  • 打赏
  • 举报
回复
Gdiplus能处理大多数图形格式,况且.png格式的又是一种很常用的格式啊?为什么会无法识别呢?

我看到有些例子是把图形先载入资源,原后采用内存复制的方式从流中读取,是不是只有这样才可以呢?

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧