/* Подключаем хедер gdlib */
#include <bgd/gd.h> // Адрес согласно первому посту. У вас может отличаться
/* Подключаем стандартный хедер для работы с файлами */
#include <stdio.h>
int main() {
/* Переменная изображения */
gdImagePtr im;
/* Указатель на файл для вывода изображения */
FILE *jpegF;
/* Переменные для цветов */
int black;
int white;
/* Создать изображение 64 ввысь, и 64 вширь */
im = gdImageCreate(64, 64);
/* Назначить черный цвет. Red = 0, Green = 0, Blue = 0.
Так как это первое назначение цвета в программе, то фон станет черным */
black = gdImageColorAllocate(im, 0, 0, 0);
/* Назначить белый цвет */
white = gdImageColorAllocate(im, 255, 255, 255);
/* Нарисовать линию белого цвета из левого верхнего угла, в правый нижний. */
gdImageLine(im, 0, 0, 63, 63, white);
/* Открыть файл для записи. "wb" означает "write binary" - бинарная запись */
jpegF = fopen("test.jpg", "wb");
/* Скопировать буфер изображения в jpeg-файл на диске */
printf("Calling gdImageJpeg... ");
gdImageJpeg(im, jpegF, 75);
printf("Ok\n");
/* Закрыть файл */
fclose(jpegF);
/* Освободить память, используемую изображением */
gdImageDestroy(im);
return 0;
}
Пример программы с gdlib или как работать с dll
Цель: Научиться работать с dll.
Средство - задача: Написать работающую программу в MSVS 2005 на C++, использующую возможности библиотеки gdlib (http://libgd.org/). Программа для начала простенькая - чертит линию на черном квадрате, и сохраняет изображения в файлы в png и jpeg формате.
Искал много - хотел найти готовые исходники простейшего примера взаимодействия с gdlib в архиве (.cpp файлы, проект, etc), и там уже смотреть, как все устроено, но не нашел.
Я новичок в c++, поэтому писать буду подробно. Делал так:
1) Скачал скомпилированную библиотеку отсюда: http://www.libgd.org/releases/gd-latest-win32.zip и распаковал.
2) Из разархивированного архива скопировал файлы из папки include в папку C:\Program Files\Microsoft Visual Studio 8\VC\include\bgd
3) Создал проект: File->New->Project->Win32 Console Application->Empty project и установил Configuration - Release (Project->Properties->Configuration)
4) Скопировал файл bgd.lib из папки lib скачанного архива в директорию программы и подключил его к проекту так:
Project->Properties->Configuration Properties->Linker->Input->Additional Dependencies прописал bgd.lib
5) Написал код программы, скомпилировал, но при запуске обнаружилось, что все рушится при попытке записи изображения в файл (функция gdImageJpeg).
Скачать архив, содержащий проект программы, можно отсюда.
Почему, по вашему мнению, программа не работает, ведь код верен?
Вопрос с использованием dll они немного проясняют, но почему конкретная программа с gdlib не работает, так и не ясно.
Привожу листинг:
Код:
Подскажите, пожалуйста, почему функция gdImageJpeg не работает?
было бы почти замечательно, если бы ещё можно было увидеть возникающие сообщения об ошибках
Согласен. Программа компилируется нормально, а при запуске предлагает запустить debuger, насколько я понимаю. Поэтому текста ошибки я не вижу.
Может у Вас больше, чем у меня опыта в подобных вопросах, и Вам удастся выявить корень зла? Вот тогда будет замечательно. Для этого, кстати, можете сами попробовать представленный проект.
а куда хоть отладчик показывает? на gdCreate?
если это какая-то runtime ошибка, то первое, что приходит в голову - он может просто не находить DLL"ку. положите DLL в system32 например или прямо возле EXEшника и попробуйте ещё раз.
или вообще DLL тут не при чём, а вы сами где-то напортачили -вот и падает... :)
т.к. возможности попробовать нету, то прийдётся угадывать. без вашей помощи - никак ;)
Цитата:
bgd.dll
gdlibexmp.exe
gdlibexmp.pdb
myimage.png (0 байт)
runme.bat
test.jpg (0 байт)
gdlibexmp.exe
gdlibexmp.pdb
myimage.png (0 байт)
runme.bat
test.jpg (0 байт)
В коде программы есть такие строчки:
Код:
/* Скопировать буфер изображения в jpeg-файл на диске */
printf("Calling gdImageJpeg... ");
gdImageJpeg(im, jpegF, 75);
printf("Ok\n");
printf("Calling gdImageJpeg... ");
gdImageJpeg(im, jpegF, 75);
printf("Ok\n");
После компиляции запускаю runme.bat, содержащий две инструкции:
Цитата:
gdlibexmp
pause
pause
И получаю на выходе: "Calling gdImageJpeg... " и предложение от Visual-Studio Just-In-Time Debugger.
Весьма вероятно, что что-то я сделал не так. Только не понимаю что. Ведь код верен, dll подключена правильно. Здесь что-то с функцией gdImageJpeg. Как Вы думаете, что это может быть?
Собственно исключение Access violation происходит при вызове импортируемой функции gdImageJpeg. Почему не знаю, пока не разбирался. Почитайте документацию, поищите sample'ы.
Цитата: nikitozz
Собственно исключение Access violation происходит при вызове импортируемой функции gdImageJpeg. Почему не знаю, пока не разбирался. Почитайте документацию, поищите sample'ы.
В том и дело, что перед тем, как создать сей топик, искал много, но безуспешно. Ранее работал с gdlib + php - подобных проблем не возникало. Надеюсь на вашу помощь.
ну, можно, например собрать проект в дебаге и всё-таки согласиться на предложении отладить ошибку. при наличии исходников проекта и библиотеки шанс успеха довольно высок )
gdlib faq в вольном переводе:
Большое спасибо <SCORP> и nikitozz за оказанную помощь!
Из
Цитата:
Microsoft Visual C++: если хотите использовать gdImageCreateFromJpeg, gdImageJpeg, или другие функции, с аргументами FILE *, пользуйтесь компилятором версии 6.0 или младше, указав при этом "multithreaded DLL" для runtime option. Если же у Вас более свежий компилятор, есть альтернативный метод: использовать функции gdImageCreateFromJpegPtr, gdImageJpegPtr, etc.
Для нашего примера, код программы нужно немного изменить. Итак, окончательный, рабочий вариант:
Код:
/* Подключаем хедер gdlib */
#include <bgd/gd.h> // Адрес согласно первому посту. У вас может отличаться
/* Подключаем стандартный хедер для работы с файлами */
#include <stdio.h>
int main() {
/* Переменная изображения */
gdImagePtr im;
/* Указатель на файл для вывода изображения */
FILE *jpegF;
/* Переменные для цветов */
int black;
int white;
/* Создать изображение 64 ввысь, и 64 вширь */
im = gdImageCreate(64, 64);
/* Назначить черный цвет. Red = 0, Green = 0, Blue = 0.
Так как это первое назначение цвета в программе, то фон станет черным */
black = gdImageColorAllocate(im, 0, 0, 0);
/* Назначить белый цвет */
white = gdImageColorAllocate(im, 255, 255, 255);
/* Нарисовать линию белого цвета из левого верхнего угла, в правый нижний. */
gdImageLine(im, 0, 0, 63, 63, white);
/* Открыть файл для записи. "wb" означает "write binary" - бинарная запись */
jpegF = fopen("test.jpg", "wb");
/* --- (Begin) --- Скопировать буфер изображения в jpeg-файл на диске --- */
printf("Saving Image... ");
/* Указатель на буфер изображения */
char *data;
/* Размер полученного буфера */
int size;
/* Записывает изображение в буфер, и устанавливает переменную size равной размеру буфера */
data = (char *) gdImageJpegPtr(im, &size, 75);
if (!data) {
printf("No data\n"); return 1;
}
if (fwrite(data, 1, size, jpegF) != size) {
printf("No write\n"); return 1;
}
/* Освобождает память, занятую буфером */
gdFree(data);
printf("Ok\n");
/* --- (End) --- Скопировать буфер изображения в jpeg-файл на диске --- */
/* Закрыть файл */
fclose(jpegF);
/* Освободить память, используемую изображением */
gdImageDestroy(im);
return 0;
}
#include <bgd/gd.h> // Адрес согласно первому посту. У вас может отличаться
/* Подключаем стандартный хедер для работы с файлами */
#include <stdio.h>
int main() {
/* Переменная изображения */
gdImagePtr im;
/* Указатель на файл для вывода изображения */
FILE *jpegF;
/* Переменные для цветов */
int black;
int white;
/* Создать изображение 64 ввысь, и 64 вширь */
im = gdImageCreate(64, 64);
/* Назначить черный цвет. Red = 0, Green = 0, Blue = 0.
Так как это первое назначение цвета в программе, то фон станет черным */
black = gdImageColorAllocate(im, 0, 0, 0);
/* Назначить белый цвет */
white = gdImageColorAllocate(im, 255, 255, 255);
/* Нарисовать линию белого цвета из левого верхнего угла, в правый нижний. */
gdImageLine(im, 0, 0, 63, 63, white);
/* Открыть файл для записи. "wb" означает "write binary" - бинарная запись */
jpegF = fopen("test.jpg", "wb");
/* --- (Begin) --- Скопировать буфер изображения в jpeg-файл на диске --- */
printf("Saving Image... ");
/* Указатель на буфер изображения */
char *data;
/* Размер полученного буфера */
int size;
/* Записывает изображение в буфер, и устанавливает переменную size равной размеру буфера */
data = (char *) gdImageJpegPtr(im, &size, 75);
if (!data) {
printf("No data\n"); return 1;
}
if (fwrite(data, 1, size, jpegF) != size) {
printf("No write\n"); return 1;
}
/* Освобождает память, занятую буфером */
gdFree(data);
printf("Ok\n");
/* --- (End) --- Скопировать буфер изображения в jpeg-файл на диске --- */
/* Закрыть файл */
fclose(jpegF);
/* Освободить память, используемую изображением */
gdImageDestroy(im);
return 0;
}
Большое спасибо <SCORP> и nikitozz за оказанную помощь!