Я нашел способ сделать это
object ABC = typeof(System.Text.StringBuilder);
dynamic _ABC = ABC;
var Instance = Activator.CreateInstance(_ABC.UnderlyingSystemType);
Да, с использованием png_set_write_fn
что-то вроде этого - непроверено:
Обновлено с изменениями из комментария
/* structure to store PNG image bytes */
struct mem_encode
{
char *buffer;
size_t size;
}
void
my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
/* with libpng15 next line causes pointer deference error; use libpng12 */
struct mem_encode* p=(struct mem_encode*)png_get_io_ptr(png_ptr); /* was png_ptr->io_ptr */
size_t nsize = p->size + length;
/* allocate or grow buffer */
if(p->buffer)
p->buffer = realloc(p->buffer, nsize);
else
p->buffer = malloc(nsize);
if(!p->buffer)
png_error(png_ptr, "Write Error");
/* copy new bytes to end of buffer */
memcpy(p->buffer + p->size, data, length);
p->size += length;
}
/* This is optional but included to show how png_set_write_fn() is called */
void
my_png_flush(png_structp png_ptr)
{
}
int save_png_to_file(RGBBitmap *bitmap, const char *path)
{
...
/* static */
struct mem_encode state;
/* initialise - put this before png_write_png() call */
state.buffer = NULL;
state.size = 0;
/* if my_png_flush() is not needed, change the arg to NULL */
png_set_write_fn(png_ptr, &state, my_png_write_data, my_png_flush);
... call png_write_png() ...
/* now state.buffer contains the PNG image of size s.size bytes */
/* cleanup */
if(state.buffer)
free(state.buffer);
#include <png.h>
#include <vector>
#include <iostream>
#include <stdlib.h>
//encode and write PNG to memory (std::vector) with libpng on C++
typedef unsigned char ui8;
#define ASSERT_EX(cond, error_message) do { if (!(cond)) { std::cerr << error_message; exit(1);} } while(0)
static void PngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length) {
std::vector<ui8> *p = (std::vector<ui8>*)png_get_io_ptr(png_ptr);
p->insert(p->end(), data, data + length);
}
struct TPngDestructor {
png_struct *p;
TPngDestructor(png_struct *p) : p(p) {}
~TPngDestructor() { if (p) { png_destroy_write_struct(&p, NULL); } }
};
void WritePngToMemory(size_t w, size_t h, const ui8 *dataRGBA, std::vector<ui8> *out) {
out->clear();
png_structp p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
ASSERT_EX(p, "png_create_write_struct() failed");
TPngDestructor destroyPng(p);
png_infop info_ptr = png_create_info_struct(p);
ASSERT_EX(info_ptr, "png_create_info_struct() failed");
ASSERT_EX(0 == setjmp(png_jmpbuf(p)), "setjmp(png_jmpbuf(p) failed");
png_set_IHDR(p, info_ptr, w, h, 8,
PNG_COLOR_TYPE_RGBA,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
//png_set_compression_level(p, 1);
std::vector<ui8*> rows(h);
for (size_t y = 0; y < h; ++y)
rows[y] = (ui8*)dataRGBA + y * w * 4;
png_set_rows(p, info_ptr, &rows[0]);
png_set_write_fn(p, out, PngWriteCallback, NULL);
png_write_png(p, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
}
Другие ответы, кажется, не полны, на мой вкус. Итак, я использовал эти ответы и другие исследования, чтобы записать черный фон в буфер. Затем, чтобы проверить, я записал буфер в файл. Это было скомпилировано с GCC. Был добавлен флаг библиотеки -lpng.
#define PNG_SETJMP_NOT_SUPPORTED
#include <stdio.h>
#include <stdlib.h>
#include <png.h>
struct libpng_inmem_write_struct { /* This is from png.c */
unsigned char * pngBfr; /* destination memory */
unsigned long pngSiz; /* destination memory size (bytes) */
};
void freeExit_w_msg(char * msg);
void wrtBgPng(png_structp pngWrtPtr, png_bytep data, png_size_t length);
png_structp pngWrtPtr; /* The pointer that points the PNG write structure */
png_infop pngWrtInfoPtr; /* The pointer that points the PNG write information */
struct libpng_inmem_write_struct p_io; /* Holds the encoded PNG data */
FILE * fw; /* The file pointer of the test file that will be wrote. */
void freeExit_w_msg(char * msg) {
if (pngWrtPtr) png_destroy_write_struct(&pngWrtPtr, &pngWrtInfoPtr);
if (p_io.pngBfr) free(p_io.pngBfr);
fclose(fw);
printf("%s\n", msg);
exit(0);
}
int main(int argc, char *argv[])
{
pngWrtInfoPtr = NULL; /* write_info_ptr */
p_io.pngBfr = NULL;
p_io.pngSiz = 0;
int imgWdth = 2558;
int imgHght = 1438;
fw = fopen (argv[1], "wb"); /* argv[1] is the name of the test file */
if (!fw) {
char msg[300];
sprintf(msg, "The file, %s, did not correctly open.\n", argv[1]);
freeExit_w_msg(msg);
}
pngWrtPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); /* write_ptr */
if (!pngWrtPtr) freeExit_w_msg((char *) "The PNG write memory did not correctly allocate.");
pngWrtInfoPtr = png_create_info_struct(pngWrtPtr);
if (!pngWrtInfoPtr) freeExit_w_msg((char *) "The PNG write information memory did not correctly allocate.");
png_set_IHDR(pngWrtPtr, pngWrtInfoPtr, imgWdth, imgHght, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_byte ** row_pointers = (png_byte **) png_malloc(pngWrtPtr, imgHght * sizeof(png_byte *));
size_t bytesPerRow = imgWdth << 2; /* 4 Bytes per pixel */
unsigned char * imgBfr = (unsigned char *) calloc(1, imgHght * bytesPerRow * sizeof(unsigned char));
for (int rw = 0; rw < imgHght; rw++) {
png_byte * rwPtr = row_pointers[rw] = (png_byte *) (imgBfr + rw * bytesPerRow);
for (int pxl = 0, byt = 0; pxl < imgWdth; pxl++) { /* Write a black background */
for (int clr = 0; clr < 3; clr++) rwPtr[byt++] = 0;
rwPtr[byt++] = 0xff;
}
}
p_io.pngBfr = (unsigned char *) malloc(4); /* Defines final PNG data location */
p_io.pngSiz = 4;
png_init_io(pngWrtPtr, (png_FILE_p) &p_io);
png_set_rows(pngWrtPtr, pngWrtInfoPtr, &row_pointers[0]);
png_set_write_fn(pngWrtPtr, &p_io, wrtBgPng, NULL);
png_write_png(pngWrtPtr, pngWrtInfoPtr, PNG_TRANSFORM_IDENTITY, NULL);
fwrite(p_io.pngBfr + 4, 1, p_io.pngSiz, fw); /* Test file */
freeExit_w_msg((char *) "The exit was normal.");
}
void wrtBgPng(png_structp pngWrtPtr, png_bytep data, png_size_t length) {
struct libpng_inmem_write_struct * p = (struct libpng_inmem_write_struct *) png_get_io_ptr(pngWrtPtr);
p->pngBfr = (unsigned char *) realloc(p->pngBfr, p->pngSiz + length); /* From png.c */
if (!p->pngBfr) freeExit_w_msg((char *) "The PNG write memory did not correctly allocate.");
memmove(p->pngBfr + p->pngSiz, data, length);
p->pngSiz += length;
}