У меня проблемы с переносом следующего кода C # на C ++:
protected override void OnPaint(CefBrowser browser, CefPaintElementType type, CefRectangle[] dirtyRects
, System.IntPtr buffer, int width, int height)
{
if (isPainting == true)
return;
isPainting = true;
// Save the provided buffer (a bitmap image) as a PNG.
using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height, width * 4, System.Drawing.Imaging.PixelFormat.Format32bppRgb, buffer))
{
bitmap.Save(@"LastOnPaint.png", System.Drawing.Imaging.ImageFormat.Png);
} // End Using bitmap
}
Что он делает:Создайте изображение из WebSite / SVG в том виде, в котором оно было отображено последней встроенной версией Chromium, и сохраните его как файл.
Итак, это соответствующий обработчик рендеринга в C ++:
void RenderHandler::OnPaint(
CefRefPtr<CefBrowser> browser,
CefRenderHandler::PaintElementType type,
const CefRenderHandler::RectList& dirtyRects,
const void* buffer, int width, int height
) {
// size_t len = sizeof(buffer) / sizeof(void*);
// printf("buffer length: %zu\n", len); // 1...
// Array size is probably: width*height * 4;
}
Итак, я посмотрел, что C # делает в конструкторе растрового изображения, а именно:
public Bitmap(int width, int height, int stride, PixelFormat format, IntPtr scan0)
{
IntPtr bitmap = IntPtr.Zero;
int status = Gdip.GdipCreateBitmapFromScan0(width, height, stride, unchecked((int)format), new HandleRef(null, scan0), out bitmap);
Gdip.CheckStatus(status);
SetNativeImage(bitmap);
}
internal void SetNativeImage(IntPtr handle) {
if (handle == IntPtr.Zero)
throw new ArgumentException(SR.GetString(SR.NativeHandle0), "handle");
nativeImage = handle;
}
Какие трассы
internal const string Gdiplus = "gdiplus.dll";
[DllImport(ExternDll.Gdiplus, SetLastError=true, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Unicode)] // 3 = Unicode
[ResourceExposure(ResourceScope.Machine)]
internal static extern int GdipCreateBitmapFromScan0(int width, int height, int stride, int format, HandleRef scan0, out IntPtr bitmap);
Так что я подумал, что могу просто вызвать GdipCreateBitmapFromScan0 в gdibitmapflat и быть почти готовым
GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width
, INT height, INT stride, PixelFormat format
, BYTE* scan0, GpBitmap** bitmap)
Итак, я собрал необходимыезаголовочные файлы для GDI, который был ужасным опытом
#ifndef __BITMAPHELPER_H__
#define __BITMAPHELPER_H__
// #define WIN32_LEAN_AND_MEAN
#pragma warning(disable:4458)
#include <Windows.h>
#include <ObjIdl.h>
#include <minmax.h>
#include <gdiplus.h>
#include <wingdi.h>
#include <gdiplusbitmap.h>
#include <gdiplusflat.h>
using namespace Gdiplus;
#pragma comment (lib,"gdiplus.lib")
#pragma warning(default:4458)
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <cstdbool>
#include <algorithm>
#include <memory>
И подумал, что вот-вот сделает это
#include "BitmapHelper.h"
static void Test()
{
GpBitmap *bitmap = NULL;
GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap); // create a bitmap object with specified width/height/color
// GpGraphics *graph;
// Image * syntaxTest = NULL;
//syntaxTest->FromFile(TEXT("d:\\abc.jpg"), true); // create an image object
// Bitmap::FromBITMAPINFO
// GpImage *image = NULL;
// Gdiplus::Image()
Bitmap *bmp = NULL;
// GdipLoadImageFromFile(TEXT("d:\\abc.jpg"), &image); // create an image object
// GdipGetImageGraphicsContext(bitmap, &graph); // create a graphic object via bitmap object
// GdipDrawImageI(graph, image, 100, 100); // draw image to this graphic object, it can be done
}
Однако оказывается, что компилятор не знает GdipCreateBitmapFromScan0, хотяэто определенно внутри #include <gdiplusflat.h>
...
Как создать растровое изображение / изображение из Scan0? Примечание: Пока я в этом, я не хочу прибегать к C ++. NET, и в идеале не к WinAPI;потому что я бы тоже хотел, чтобы он работал на Linux.И не к такой чудовищной зависимости, как SDL.
Пока, похоже, мои возможные альтернативы используют этот код:
https://codereview.stackexchange.com/questions/196084/read-and-write-bmp-file-in-c
, что означает, что я должен создать заголовок растрового изображения myselfs.Или я мог бы использовать некоторый код из ImageIO .
Я не могу поверить, что создание простого растрового изображения даже на одной операционной системе - это так сложно ...
Неужели нет лучшего (и портативного) способа создания простого растрового изображения из тривиального массива цветов пикселей?И почему компилятор не находит GdipCreateBitmapFromScan0?Если бы я использовал LoadLibrary и GetProcAddress, чтобы вызвать его, вместо того, чтобы искать файлы заголовков Windows, я бы уже закончил ...И почему #include <gdiplus.h>
не включает свои собственные зависимости?