Gdi+ 加载Gif图片(BYTE*转为IStream)

今天工作中遇到GDI+加载图片流的问题,网上找了很多资料都不行,绘制其他帧总是模糊,,

网上的方法代码如下:

注:pImageData是BYTE*类型 ,dImageLen是DWORD类型;

HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, dImageLen);
BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
memcpy(pmem,pImageData,dImageLen);
IStream* pstm;
HRESULT ht =  CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
if (ht != S_OK)
{
	GlobalFree(m_hMem);
	return ;
}
m_pImage=Gdiplus::Image::FromStream(pstm);
GlobalUnlock(m_hMem);   

pstm->Release();
GlobalFree(m_hMem); 

if (m_pImage)
{
	UINT count = m_pImage->GetFrameDimensionsCount();
	if (count > 0 && m_pImage->GetLastStatus() == 0)
	{
		m_pDimensionIDs = new GUID[count];
		m_pImage->GetFrameDimensionsList(m_pDimensionIDs, count);
		WCHAR strGuid[39];
		StringFromGUID2(m_pDimensionIDs[0], strGuid, 39);
		m_FrameCount = m_pImage->GetFrameCount(&m_pDimensionIDs[0]);
		UINT TotalBuffer = m_pImage->GetPropertyItemSize(PropertyTagFrameDelay);
		m_pItem = (Gdiplus::PropertyItem*)malloc(TotalBuffer);
		m_pImage->GetPropertyItem(PropertyTagFrameDelay, TotalBuffer, m_pItem);
		m_bStatOK = TRUE;
	}
}

 总是绘制出现问题后自己找了方法解决问题,代码如下:

注:m_pstream是类成员,在类析构的时候释放 ,,,pImageData是BYTE*类型 ,dImageLen是DWORD类型;

if(CreateStreamOnHGlobal(NULL, TRUE, &m_pStream) == S_OK)
	{
		ULONG ulWritten = 0;
		m_pStream->Write(pImageData, dImageLen, &ulWritten);

		//Rewind the argument stream;
		LARGE_INTEGER lInt;
		lInt.QuadPart = 0;
		m_pStream->Seek(lInt, STREAM_SEEK_SET, NULL);

		//Read the lenght of the argument stream;
		STATSTG statSTG;
		long dwResult = m_pStream->Stat(&statSTG, STATFLAG_DEFAULT);
		if(dwResult != S_OK)
		{
			return ;
		}
		m_pImage=Gdiplus::Image::FromStream(m_pStream);
		if (m_pImage)
		{
			UINT count = m_pImage->GetFrameDimensionsCount();
			if (count > 0 && m_pImage->GetLastStatus() == 0)
			{
				m_pDimensionIDs = new GUID[count];
				m_pImage->GetFrameDimensionsList(m_pDimensionIDs, count);
				WCHAR strGuid[39];
				StringFromGUID2(m_pDimensionIDs[0], strGuid, 39);
				m_FrameCount = m_pImage->GetFrameCount(&m_pDimensionIDs[0]);
				UINT TotalBuffer = m_pImage->GetPropertyItemSize(PropertyTagFrameDelay);
				m_pItem = (Gdiplus::PropertyItem*)malloc(TotalBuffer);
				m_pImage->GetPropertyItem(PropertyTagFrameDelay, TotalBuffer, m_pItem);
				m_bStatOK = TRUE;
			}
		}
	}

这样通过定时器绘制其他帧就没有图片不成像问题

DrawGif(HDC hDC, const RECT& rc)
{
	if (NULL == m_pItem)
		return 0;

    m_pImage->SelectActiveFrame(&Gdiplus::FrameDimensionTime, m_iCurrentFrame);

    unsigned msec = ((int*)m_pItem->value)[m_iCurrentFrame] * 10;

	Graphics g( hDC );
	g.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
	g.DrawImage( m_pImage, rc.left, rc.top, rc.right-rc.left, rc.bottom - rc.top );

    return msec;
}

  

时间: 2024-10-14 08:54:58

Gdi+ 加载Gif图片(BYTE*转为IStream)的相关文章

win32用GDI+加载png图片作为背景图

#include <windows.h> #include <gdiplus.h> /* GDI+ startup token */ ULONG_PTR gdiplusStartupToken; /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); // UpdateLayeredWindow Defination typedef BOOL(*UP

有效解决Android加载大图片时内存溢出的问题

首先解析一下基本的知识: 位图模式,bitmap颜色位数是1位 灰度模式,bitmap颜色位数是8位,和256色一样 RGB模式,bitmap颜色位数是24位 在RGB模式下,一个像素对应的是红.绿.蓝三个字节 CMYK模式,bitmap颜色位数是32位  在CMYK模式下,一个像素对应的是青.品.黄.黑四个字节 图像文件的字节数(Byte) = 图像分辨率*颜色深度/8(bit/8) 例如:一幅640*480图像分辨率.RGB色一般为24位真彩色,图像未经压缩的数据容量为:640X480X24

[android] 加载大图片到内存

默认情况下,android程序分配的堆内存大小是16,虚拟机上面的VM Heep就是设置它的 一个图片所占的内存,比如1920*2560像素的图片需要,1920*2560*3至少这些的内存byte 找到ImageView控件对象 调用BitmapFactory对象的decodeFile(pathName)方法,来获取一个位图对象,参数:pathName是String类型的图片路径 把图片导入到手机的sdcard目录下面 调用ImageView对象的setImageBitmap(bitemap)方

图片--Android有效解决加载大图片时内存溢出的问题

Android有效解决加载大图片时内存溢出的问题 博客分类: Android Android游戏虚拟机算法JNI 尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存. 因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView

Viewpager图片自动轮播,网络图片加载,图片自动刷新

package com.teffy.viewpager; import java.util.ArrayList; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import android.annotation.SuppressLint; import android.app.Act

MFC加载PNG图片并实现双缓冲

因为PNG包含Alpha通道,所以不同于BITMAP,在MFC中使用CImage类对其进行处理,通常使用load和draw成员函数. 所以标题的论述可以进一步解释为,使用CImage实现双缓冲. 通常的双缓冲方法为(首先将消息函数afx_msg BOOL OnEraseBkgnd(CDC* pDC)的函数体改为return TRUE): CDC memDC; CBitmap bmp; bmp.CreateCompatibleBitmap(pDC,WINDOW_WIDTH,WINDOW_HEIGH

Android(java)学习笔记236:多媒体之加载大图片到内存(Bitmap API)

1.Bitmap (API使用) android里面的bitmap中,一个像素点需要4个byte去表示,这是因为android表示颜色是" argb ":其中 a 表示是透明度,然后是" rgb" 颜色表示范围 00000000 ~~~ffffffff 2.加载图片到内存: 上面说到了图形表示使用4byte,和int一样,所以Android里面每个像素点都是使用一个int来表示的. Bitmap bitmap = BitmapFactory.decodeResour

图片预加载与图片懒加载的区别与实现

预加载与懒加载,我们经常经常用到,这些技术不仅仅限于图片加载,我们今天讨论的是图片加载: 一.什么是图片预加载与懒加载: 图片预加载:顾名思义,图片预加载就是在网页全部加载之前,提前加载图片.当用户需要查看时可直接从本地缓存中渲染,以提供给用户更好的体验,减少等待的时间.否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白,这样浏览者可能以为图片预览慢而没兴趣浏览,把网页关掉,这时,就需要图片预加载.当然这种做法实际上牺牲了服务器的性能换取了更好的用户体验. 图

iOS面试题之加载单张图片到底会不会崩溃?

今天,一哥们去某公司面试iOS职位.其中一道题目问,加载一张图片,到底会不会崩溃呢? 我拿到这个问题,当时以为是获取网络图片,那还是可能崩溃的,但实际问题,还有半句,图片是本地的... 这问题,加载本地的怎么会崩溃呢?写这么久加载图片也没遇到如此问题. =================================================== 原来,iPhone毕竟是手持设备,它所占有的内存是有限的,当图片过大的时候会引起内存导致的崩溃现象. 后来,我又查了下,发现,原来还有这么大学