首页
社区
课程
招聘
[求助]请问PNG文件定义到资源文件中的问题
发表于: 2008-3-7 22:19 7903

[求助]请问PNG文件定义到资源文件中的问题

2008-3-7 22:19
7903
各位大侠客,从文件调用PNG文件的方法我已经会啦,但PNG文件可不可定义到资源文件中呢?如果可以,那么怎样调用呢?我从GDI和GDI+里都没有找到调用的API。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
2
可以使用RCDATA将*.png图片加入资源。
格式:
ResNameOrId RCDATA *.png

加入资源后,只须使用FindResource/LoadResource/LockResource函数获取*.png资源。
用SetDIBitsToDevice或StretchDIBits函数将*.png设置到设备环境中。
2008-3-7 23:28
0
雪    币: 253
活跃值: (250)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
3
谢谢 小虾 大侠客!
2008-3-8 14:22
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
4
以前看过MSDN里的声明SetDIBitsToDevice和StretchDIBits函数可以转化PNG和JPG图像,一直没有试验过,今天按MSDN的代码竟然试了几次都没有成功。呵呵,不知哪里有问题。

JPEG and PNG Extensions for Specific Bitmap Functions and Structures
On certain versions of Microsoft® Windows®, the StretchDIBits and SetDIBitsToDevice functions allow JPEG and PNG images to be passed as the source image to printer devices. This extension is not intended as a means to supply general JPEG and PNG decompression to applications, but rather to allow applications to send JPEG- and PNG-compressed images directly to printers having hardware support for JPEG and PNG images.

The BITMAPINFOHEADER, BITMAPV4HEADER and BITMAPV5HEADER structures are extended to allow specification of biCompression values indicating that the bitmap data is a JPEG or PNG image. These compression values are only valid for SetDIBitsToDevice and StretchDIBits when the hdc parameter specifies a printer device. To support metafile spooling of the printer, the application should not rely on the return value to determine whether the device supports the JPEG or PNG file. The application must issue QUERYESCSUPPORT with the corresponding escape before calling SetDIBitsToDevice and StretchDIBits. If the validation escape fails, the application must then fall back on its own JPEG or PNG support to decompress the image into a bitmap.

Testing a Printer for JPEG or PNG Support
The SetDIBitsToDevice function uses color data from a DIB to set the pixels in the specified rectangle on the device that is associated with the destination device context.

Windows 98/Me, Windows 2000/XP: SetDIBitsToDevice is extended to allow a JPEG or PNG image to be passed as the source image.

For example:

//
// pvJpgImage points to a buffer containing the JPEG image
// nJpgImageSize is the size of the buffer
// ulJpgWidth is the width of the JPEG image
// ulJpgHeight is the height of the JPEG image
//

//
// Check if CHECKJPEGFORMAT is supported (device has JPEG support)
// and use it to verify that device can handle the JPEG image.
//

ul = CHECKJPEGFORMAT;

if (
    // Check if CHECKJPEGFORMAT exists:

    (ExtEscape(hdc, QUERYESCSUPPORT,
               sizeof(ul), &ul, 0, 0) > 0) &&

    // Check if CHECKJPEGFORMAT executed without error:

    (ExtEscape(hdc, CHECKJPEGFORMAT,
               pvJpgImage, nJpgImageSize, sizeof(ul), &ul) > 0) &&

    // Check status code returned by CHECKJPEGFORMAT:

    (ul == 1)
   )
{
    //
    // Initialize the BITMAPINFO.
    //

    memset(&bmi, 0, sizeof(bmi));
    bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth       = ulJpgWidth;
    bmi.bmiHeader.biHeight      = -ulJpgHeight; // top-down image
    bmi.bmiHeader.biPlanes      = 1;
    bmi.bmiHeader.biBitCount    = 0;
    bmi.bmiHeader.biCompression = BI_JPEG;
    bmi.bmiHeader.biSizeImage   = nJpgImageSize;

    //
    // Do the SetDIBitsToDevice.
    //

    iRet = SetDIBitsToDevice(hdc,
                             ulDstX, ulDstY,
                             ulDstWidth, ulDstHeight,
                             0, 0,
                             0, ulJpgHeight,
                             pvJpgImage,
                             &bmi,
                             DIB_RGB_COLORS);

    if (iRet == GDI_ERROR)
        return FALSE;
}
else
{
    //
    // Decompress image into a DIB and call SetDIBitsToDevice
    // with the DIB instead.
    //
}
2008-3-8 16:43
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
5
是不是该用BI_PNG
2008-3-8 17:06
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
6
我的试验代码是用BI_PNG的,不过,VC6没有BI_JPG和BI_PNG常数定义,在网上找了一下,这两个参数的定义值是#define BI_JPG 4L和#define BI_PNG 5L。
//曾经这样测试过,不过,没成功。
#define BI_JPG 4L
#define BI_PNG 5L
// 创建BMP内存DC
l_hWndDC = GetDC(hWnd);
l_hMemDC = CreateCompatibleDC(hWndDC);
l_hBitmap = CreateCompatibleBitmap(l_hWndDC, 128, 128); // png图像长宽都是128
SelectObject(l_hMemDC, l_hBitmap);

//初始化BitmapInfo结构
l_stBI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
l_stBI.bmiHeader.biWidth = 128;  // Png长宽
l_stBI.bmiHeader.biHeight = 128;
l_stBI.bmiHeader.biPlanes = 1;
l_stBI.bmiHeader.biBitCount = 0;
l_stBI.bmiHeader.biCompression = BI_PNG;
l_stBI.bmiHeader.biSizeImage   = 0x292e; // PNG文件字节大小
// g_pvPngDataBuff指向*.png二进制数据
if (SetDIBitsToDevice(l_hMemDC,0,0,128,128,0,0,0,128,g_pvPngDataBuff,&l_stBI,DIB_RGB_COLORS))
{
    MessageBox(0,"成功转化PNG图像","成功!",MB_OK);
}else
{
    // 到这里总是返回0
    MessageBox(0,"转化失败!",NULL,MB_OK);
}
2008-3-8 18:19
0
雪    币: 253
活跃值: (250)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
7
这个问题可不可以用GDI+来解决?在GDI+中使用PNG文件只要3个API:

invoke MultiByteToWideChar,CP_OEMCP,MB_PRECOMPOSED,CTXT("start_top.png"),-1,addr FileName_UNICODE,255        ;ASCII转成UNICODE
invoke GdipLoadImageFromFile,addr FileName_UNICODE,addr image        ;调用图片文件
invoke GdipDrawImageRectI,gp,image,0,0,380,67        ;显示图片

而如果使用BMP的资源只要两个API:
invoke GdipCreateBitmapFromResource,hInstance,9107,addr image        ;从资源中调出位图
invoke GdipDrawImageRectI,gp,image,0,0,380,67        ;显示图片

可惜GdipCreateBitmapFromResource这个函数好象只支持BMP格式的资源。在资源中使用PNG文件,是不是也只要几个API就行呢?目前我还没有成功,FindResource/LoadResource/LockResource调入的RCDATA资源需要进行解码,不知道如何进行解码,有没有朋友帮忙看一下这个问题?
2008-3-9 12:59
0
雪    币: 253
活跃值: (250)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
8
晕啦,想要使用PNG的资源(JPG的也一样),需要这样做:
invoke FindResource,hInstance,9107,RT_RCDATA
mov hResInfo,eax
invoke LoadResource,hInstance,eax
invoke LockResource,eax
mov pResourceData,eax
invoke SizeofResource,hInstance,hResInfo
mov imageSize,eax
invoke GlobalAlloc,GMEM_FIXED,imageSize
mov pBuffer,eax
invoke MemCopy,pResourceData,pBuffer,imageSize
invoke CreateStreamOnHGlobal,pBuffer,FALSE,addr pStream
invoke GdipCreateBitmapFromStream,pStream,addr image
invoke GdipDrawImageRectI,gp,image,0,0,380,67        ;显示图片
invoke GdipDisposeImage,image
invoke GlobalFree,pBuffer
不知有没有更简单的方法。
2008-3-10 19:30
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
9
我没有使用过GDI+函数,不过如果不用GDI+函数,似乎只有自己写解码函数或下载别人的解码库才行了。
2008-3-10 20:18
0
雪    币: 193
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
我用 CxImage 库,而且支持 Win9X.
2008-4-1 13:46
0
游客
登录 | 注册 方可回帖
返回
//