在内存中创建GDI +位图,然后另存为png

编程入门 行业动态 更新时间:2024-10-28 09:17:14
本文介绍了在内存中创建GDI +位图,然后另存为png的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我对C ++非常新,并且在编写一个使用GDI +库在内存中创建一个新的位图(因此不打开/读取现有位图)的函数时遇到了麻烦。然后绘制位图;然后将位图保存为png。特别是,我有位图创建和保存代码的问题。我被限制使用代码块,所以不能使用视觉工作室,即使我想。代码如下:

I am very new to C++ and been having trouble with writing a function that uses the GDI+ library to create a new bitmap in memory ( so not opening/reading an existing bitmap); then drawing on the bitmap; before saving the bitmap as a png. In particular, I am having problems with the bitmap creation and saving code. I am constrained to using codeblocks and so can't use visual studios, even if I wanted to. The code is as follows:

#include "drawImage.h" #include <windows.h> #include <objidl.h> #include <gdiplus.h> #include <stdio.h> #include <iostream> using namespace std; using namespace Gdiplus; drawImage::drawImage(){} void drawImage::DrawBitmap(int width, int height){ GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); { //Create a bitmap Bitmap myBitmap(width, height, PixelFormatCanonical); Graphics g(&myBitmap); Pen blackpen(Color(255,0,0,0), 3); //draw on bitmap int x1 = 1; int x2 = 200; int y1 = 1; int y2 = 200; g.DrawLine(&blackpen, x1,y1,x2,y2); // Save bitmap (as a png) CLSID pngClsid; GetEncoderClsid(L"image/png", &pngClsid); myBitmap.Save(L"C:\\test\\test.png", &pngClsid, NULL); } GdiplusShutdown(gdiplusToken); }

我使用此代码的问题如下:

The issues I have been having with this code are as follows:

  • 保存代码未编译时出现错误消息GetEncoderClsid'未在此范围中声明。但是,我直接从Microsoft网站这里,所以不知道我做错了什么,虽然我不认为这是将位图转换为png的正确方法,但我不知道任何替代方法?

  • The 'saving' code does not compile with an error message of "'GetEncoderClsid' was not declared in this scope". However, I got this direct from the Microsoft website here and so don't know what I am doing wrong, although I don't think this is the proper way of converting bitmap to png but I dont know any alternative way?

    当代码编译并运行时(通过注释保存代码),它会在Bitmap * myBitmap = new Bitmap(width,height,PixelFormatCanonical)

    When the code is compiled and run (by commenting out the saving code), it then crashes on the line "Bitmap *myBitmap = new Bitmap(width, height, PixelFormatCanonical);" with an error message saying my executable has stopped working.

    我已经添加了'gdi32'链接器库, -lgdiplus'作为链接器选项。此外,我已使用此网站来帮助gdi的东西,虽然位图的部分只处理加载现有的位图(不会在内存中创建新的位图)

    I have added the 'gdi32' linker library and also '-lgdiplus' as a linker option. Also, I have used this website to help with the gdi stuff although the section on bitmaps only deals with loading existing bitmaps (not creating new ones in memory)

    我完全迷失在做什么,所以任何帮助或建议在这件事情是非常赞赏。

    I am totally lost on what to do, so any help or advice on this matter is much appreciated.

    推荐答案

    核心问题是将错误的像素格式传递到位图构造函数。 PixelFormatCanonical 不是受支持的像素格式。这是一个位掩码,用于确定像素格式是否是规范的(请参阅 IsCanonicalPixelFormat )。您必须使用真实的像素格式,例如默认的 PixelFormat32bppARGB 。

    The core issue is passing the wrong pixel format to the Bitmap constructor. PixelFormatCanonical is not one of the supported pixel formats. It's a bit mask used to determine whether a pixel format is canonical (see IsCanonicalPixelFormat). You'll have to use a real pixel format, like the default PixelFormat32bppARGB.

    输出:

    首先是一个用于GDI +初始化的小助手类。这确保了在所有其他对象被销毁之后,执行dor(即调用 GdiplusShutdown )。关于销毁的顺序,它的作用与操作手册中的附加范围相同。此外,它还允许抛出异常。

    First up, a small helper class for GDI+ initialization. This ensures, that the d'tor (i.e. the call to GdiplusShutdown) is executed after all other objects have been destroyed. With respect to order of destruction, it serves the same purpose as the additional scope in the OP. In addition, it also allows for exceptions to be thrown.

    #include <windows.h> #include <gdiplus.h> using namespace Gdiplus; #include <stdexcept> using std::runtime_error; struct GdiplusInit { GdiplusInit() { GdiplusStartupInput inp; GdiplusStartupOutput outp; if ( Ok != GdiplusStartup( &token_, &inp, &outp ) ) throw runtime_error( "GdiplusStartup" ); } ~GdiplusInit() { GdiplusShutdown( token_ ); } private: ULONG_PTR token_; };

    此代码取自MSDN示例检索编码器的类标识符。

    This code was taken from the MSDN sample Retrieving the Class Identifier for an Encoder.

    int GetEncoderClsid( const WCHAR* format, CLSID* pClsid ) { UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize( &num, &size ); if ( size == 0 ) return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)( malloc( size ) ); if ( pImageCodecInfo == NULL ) return -1; // Failure GetImageEncoders( num, size, pImageCodecInfo ); for ( UINT j = 0; j < num; ++j ) { if ( wcscmp( pImageCodecInfo[j].MimeType, format ) == 0 ) { *pClsid = pImageCodecInfo[j].Clsid; free( pImageCodecInfo ); return j; // Success } } free( pImageCodecInfo ); return -1; // Failure }

    最后,GDI +渲染代码。它使用具有自动存储持续时间的对象,使其更紧凑和更安全。

    Finally, the GDI+ rendering code. It uses objects with automatic storage duration throughout, making it more compact and safer.

    void drawImage( int width, int height ) { GdiplusInit gdiplusinit; //Create a bitmap Bitmap myBitmap( width, height, PixelFormat32bppARGB ); Graphics g( &myBitmap ); Pen blackpen( Color( 255, 0, 0, 0 ), 3 ); //draw on bitmap g.DrawLine( &blackpen, 1, 1, 200, 200 ); // Save bitmap (as a png) CLSID pngClsid; int result = GetEncoderClsid( L"image/png", &pngClsid ); if ( result == -1 ) throw runtime_error( "GetEncoderClsid" ); if ( Ok != myBitmap.Save( L"C:\\test\\test.png", &pngClsid, NULL ) ) throw runtime_error( "Bitmap::Save" ); } int main() { drawImage( 200, 200 ); return 0; }

    注意:看起来像 GetEncoderClsid 不应该是必需的,因为那些是众所周知的常量。但是,尝试传递适当的 WIC CLSID ( CLSID_WICPngEncoder )到 Bitmap :: Save 只产生一个 FileNotFound 错误。

    Note: It looks like GetEncoderClsid shouldn't be required, since those are well-known constants. However, trying to pass the appropriate WIC CLSID (CLSID_WICPngEncoder) to Bitmap::Save only produced a FileNotFound error.

  • 更多推荐

    在内存中创建GDI +位图,然后另存为png

    本文发布于:2023-07-26 19:03:28,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1217909.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:位图   另存为   内存   png   GDI

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!