Используя GTK + 3.6, я хотел бы отображать изображение из буфера в памяти, а не из файла на диске. у меня есть const char *data
с данными изображения, и я пытаюсь создать изображение GTK из него.
До сих пор я пробовал два подхода, которые, как я думал, могли бы работать. Оба используют GdkPixbuf и поэтому требуют, чтобы данные изображения были guchar* (unsigned char*)
,
С этим требованием я должен привести данные:
guchar *gudata = reinterpret_cast<guchar*>(const_cast<char*>(data));
Затем я попробовал следующее:
Запись данных в GdkPixbufLoader с gdk_pixbuf_loader_write
, Здесь я получаю ошибку "Unrecognized image file format"
или если я создаю загрузчик с определенным типом (jpg), я получаю сообщение об ошибке, говорящее о том, что это не формат файла JPG (об этом рассказывается ниже).
РЕДАКТИРОВАТЬ: немного кода:
guchar *gudata = reinterpret_cast<guchar*>(const_cast<char*>(data));
int stride = ((1056 * 32 + 31) & ~31)/8;
GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
GError *error = NULL;
if(!gdk_pixbuf_loader_write(loader, gudata, data_size, &error)
{
printf("Error:\n%s\n", error->message);
}
РЕДАКТИРОВАТЬ 01/01/2013:
Удален параметр шага из функции записи — опечатка.
Каирская поверхность не работает так же хорошо. Показывает черный экран и шум.
Инициализация pixbuf с gdk_pixbuf_new_from_data
и затем изображение просто выглядит как телевизионный шум, который указывает на то, что либо данные неверны (и они были преобразованы), либо что другие параметры были неверны (строка изображения скачет, но это не так :)).
После ошибок я просто попытался записать данные в файл foo.jpg
с помощью ofstream
и да, я получаю правильно работающий файл изображения. file
команда в терминале подтверждает, что это изображение в формате JPEG, и с помощью простого блока кода я создал GdkPixbuf из этого foo.jpg, чтобы проверить его значение шага строки и оно соответствует значению, которое я передаю вышеупомянутой функции.
Повреждаются ли данные изображения с использованием приведения, и если да, то как я могу это исправить? Я получаю данные изображения в const char*
, Я посмотрел на QtPixmap, и он также загружает unsigned char*
,
Нужно ли использовать отдельную библиотеку? (Libjpeg?)
У меня установлен libgtk3-dev.
Спасибо!
01.03.2012 ОБНОВЛЕНИЕ:
Вот простое работающее приложение, которое загружает файл «test.jpg» рядом с ним (размер файла должен быть < 100000 байт).
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
void on_destroy (GtkWidget *widget G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED)
{
gtk_main_quit ();
}
int main (int argc, char *argv[])
{
FILE *f;
guint8 buffer[100000];
gsize length;
GdkPixbufLoader *loader;
GdkPixbuf *pixbuf;
GtkWidget *window;
GtkWidget *image;
gtk_init (&argc, &argv);
f = fopen ("test.jpg", "r");
length = fread (buffer, 1, sizeof(buffer), f);
fclose (f);
loader = gdk_pixbuf_loader_new ();
gdk_pixbuf_loader_write (loader, buffer, length, NULL);
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
image = gtk_image_new_from_pixbuf (pixbuf);
gtk_container_add (GTK_CONTAINER (window), image);
gtk_widget_show_all (GTK_WIDGET (window));
g_signal_connect (window, "destroy", G_CALLBACK(on_destroy), NULL);
gtk_main ();
return 0;
}
Оригинальный ответ:
char *
или же unsigned char *
здесь имеет мало значения.
gdk_pixbuf_new_from_data
будет считывать только несжатые данные RGB (единственное поддерживаемое цветовое пространство — GDK_COLORSPACE_RGB) с альфа-каналом (RGBA) или без него (RGB). Неудивительно, что передать его JPEG не удается.
призвание gdk_pixbuf_loader_write
выглядит лучше, но нам нужен код, чтобы увидеть, что вы делаете неправильно. Однако убедитесь, что у вас установлен загрузчик pixbuf для jpg, запустив в gdk-pixbuf-query-loaders
команда и проверка наличия JPEG.
Других решений пока нет …