Вернуться к разделу "Реализация проекта BookScanLib ".


1. Знакомство с FreeImage.

На первом этапе проекта BookScanLib мы создаём каркасное консольное Win32-приложение на базе FreeImage. Оно может быть использовано как для первого знакомства с библиотекой FreeImage, так и как отправная точка для всего проекта.

FreeImage - это свободно-бесплатная графическая библиотека. Последняя её версия - 3.9.2.

Библиотека FreeImage поставляется в 2 вариантах на выбор:

1. Source distribution - в виде набора полных исходников. FreeImage добавляется в Вашу программу как статическая библиотека.

2. Binary distribution - в виде DLL-библиотеки плюс заголовочный файл к ней. FreeImage добавляется в Вашу программу как динамическая библиотека.

Библиотека FreeImage написана на языке программирования Си.

Пока что давайте остановимся на наипростейшем варианте поставки - на втором (Binary distribution).

Этому варианту соответствует пакет:  Download FreeImage 3.9.2 [WIN32]   (1,0 МБ)

Так как в этом пакете есть много не нужных нам пока файлов, то его можно сейчас не скачивать, а взамен скачать составленную мною его облегчённую версию:

FreeImage DLL v3.9.2  (432 КБ)

Этот мини-пакет в дальнейшем потребуется нам при написании КАЖДОГО алгоритма библиотеки (в виде FreeImage-программы). Там внутри только 3 файла (+ readme к ним): dll-библиотека, заголовочный и компоновочный файлы к ней.

Кроме того, библиотека FreeImage имеет общий пакет документации в формате Pdf:

FreeImage Documentation   (1,99 МБ)

Этот пакет рекомендуется скачать всем с самого начала и начинать постепенно знакомиться с ним.

В дальнейшем, быть может, будет создан усечённый вариант библиотеки FreeImage - путём удаления оттуда "лишней" функциональности - в целях уменьшения её размера. Однако пока что, на этапе разработки алгоритмов, это совершенно несущественно - подобное "усечение" можно будет сделать в самый последний момент.

В первую очередь давайте попробуем получить каркасное (т.е. наипростейшее) консольное Win32 FreeImage-приложение. Такое приложение можно составить на базе примеров, изложенных в документации FreeImage Documentation.

Я сделал такую программу и назвал её fi_demo. Вот её компиляционный проект для MS Visual C++ v6.0:

FreeImage Demo    (15 КБ)

Это - простейшая консольная программа, она принимает на входе графический файл любого поддерживаемого формата (через командную строку по его имени) и сохраняет его как "test.png". (Для работы программы требуется FreeImage dll-библиотека из пакета FreeImage DLL v3.9.2 - см. выше).

Ниже приводится полный исходный код этой программы:


// ==========================================================
// This is a FreeImage 3.92 Example
//
// Load From File Demo
//
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
// THIS DISCLAIMER.
//
// Use at own risk!
// ==========================================================
//
//   This example shows how to load a graphical file from the hard disk using the FreeImage
//   Library
// 
// Functions used in this sample:
//
// FreeImage_GetFormatFromFIF, FreeImage_GetFileType, FreeImage_GetFIFFromFilename,
// FreeImage_FIFSupportsReading, FreeImage_Load, FreeImage_SetOutputMessage, FreeImage_Save,
// FreeImage_Unload. 
//
// ==========================================================

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include "FreeImage.h"

// ----------------------------------------------------------

/**
FreeImage error handler
@param fif Format / Plugin responsible for the error 
@param message Error message
*/
void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) {
	printf("\n*** "); 
	printf("%s Format\n", FreeImage_GetFormatFromFIF(fif));
	printf(message);
	printf(" ***\n");
}

// ----------------------------------------------------------

/** Generic image loader

  @param lpszPathName Pointer to the full file name
  @param flag Optional load flag constant
  @return Returns the loaded dib if successful, returns NULL otherwise
*/

FIBITMAP* GenericLoader(const char* lpszPathName, int flag)
{	
	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
	// check the file signature and deduce its format
	// (the second argument is currently not used by FreeImage)
	
	fif = FreeImage_GetFileType(lpszPathName, 0);
	
	if(fif == FIF_UNKNOWN)
	{
		// no signature ?
		// try to guess the file format from the file extension
		fif = FreeImage_GetFIFFromFilename(lpszPathName);
	}
	
	// check that the plugin has reading capabilities ...
	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))
	{
		// ok, let's load the file
		FIBITMAP *dib = FreeImage_Load(fif, lpszPathName, flag);
		
		// unless a bad file format, we are done !
		return dib;
	}
	
	return NULL;
}

// ----------------------------------------------------------

int main(int argc, char *argv[]) {
	
	// call this ONLY when linking with FreeImage as a static library
#ifdef FREEIMAGE_LIB
	FreeImage_Initialise();
#endif // FREEIMAGE_LIB
	
	// initialize your own FreeImage error handler
	
	FreeImage_SetOutputMessage(FreeImageErrorHandler);
	
	if(argc != 2) {
		printf("Usage : fi_demo <input file name>\n");
		return 0;
	}
	
	FIBITMAP *dib = GenericLoader(argv[1], 0);
	
	if (dib)
	{		
		// bitmap successfully loaded!
		
		// save the bitmap as a PNG ...
		const char *output_filename = "test.png";
		
		// first, check the output format from the file name or file extension
		FREE_IMAGE_FORMAT out_fif = FreeImage_GetFIFFromFilename(output_filename);
		
		if(out_fif != FIF_UNKNOWN)
		{
			// then save the file
			FreeImage_Save(out_fif, dib, output_filename, 0);
		}
		
		// free the loaded FIBITMAP
		FreeImage_Unload(dib);
		
	}
	
	// call this ONLY when linking with FreeImage as a static library
#ifdef FREEIMAGE_LIB
	FreeImage_DeInitialise();
#endif // FREEIMAGE_LIB
	
	return 0;
}

Краткое описание используемых функций

Примечание: более подробную информацию о библиотеке FreeImage и об используемых в ней функциях смотрите в её англоязычной документации FreeImage Documentation (1,99 МБ).


FreeImage_GetFormatFromFIF

DLL_API  const char*  DLL_CALLCONV   FreeImage_GetFormatFromFIF(FREE_IMAGE_FORMAT fif);

Возвращает строку - название графического формата.

На входе принимает "тип файла" (значение типа FREE_IMAGE_FORMAT - в библиотеке FreeImage это символическое обозначение графического типа данных - см. Таблицу 1 внизу страницы).


FreeImage_GetFileType

DLL_API  FREE_IMAGE_FORMAT  DLL_CALLCONV  FreeImage_GetFileType(const char *filename, int size FI_DEFAULT(0));

Определяет тип графического файла - путём анализа его характерного содержимого (сигнатуры).

На входе принимает строку - путь к графическому файлу на диске. Входной параметр size пока не используется и выставляется в ноль. В случае удачи функция возвращает "тип файла" (значение типа FREE_IMAGE_FORMAT).

warning.gif (1787 bytes) В случае неудачи (т.к. не всегда возможно определить тип графического файла по его сигнатуре) функция возвращает FIF_UNKNOWN, и тогда остаётся последний шанс - попытаться вычислить тип данного графического файла при помощи функции FreeImage_GetFIFFromFilename, которая судит о типе файла просто по его расширению (что, естественно, ненадёжно и медленно).

FreeImage_GetFIFFromFilename

DLL_API  FREE_IMAGE_FORMAT  DLL_CALLCONV   FreeImage_GetFIFFromFilename(const char *filename);

Определяет тип графического файла просто по его расширению.

На входе принимает строку - путь к графическому файлу на диске. Возвращает "тип файла" (значение типа FREE_IMAGE_FORMAT). Это медленная и ненадёжная функция (по самой своей сути).


FreeImage_FIFSupportsReading

DLL_API  BOOL  DLL_CALLCONV   FreeImage_FIFSupportsReading(FREE_IMAGE_FORMAT fif);

Проверяет, поддерживается ли данный графический формат на чтение.

На входе принимает "тип файла" (значение типа FREE_IMAGE_FORMAT), возвращает TRUE / FALSE.


FreeImage_Load

DLL_API  FIBITMAP*  DLL_CALLCONV  FreeImage_Load(FREE_IMAGE_FORMAT fif, const char *filename, int flags FI_DEFAULT(0));

Загружает в память графический файл с диска.

На входе принимает "тип файла" (значение типа FREE_IMAGE_FORMAT), строку - путь к графическому файлу на диске, опции открытия файла (по умолчанию ноль). Возвращает указатель на значение типа FIBITMAP ("графический файл, загруженный в память").


FreeImage_SetOutputMessage

DLL_API  void  DLL_CALLCONV   FreeImage_SetOutputMessage(FreeImage_OutputMessageFunction omf);

Задаёт имя функции - обработчика ошибок.

Поведение обработчика ошибок зависит от "типа файла" (значение типа FREE_IMAGE_FORMAT), при работе с которым возникла ошибка.

/** 
FreeImage error handler 
@param fif Format / Plugin responsible for the error 
@param message Error message 
*/ 
void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) { 
	printf("\n*** "); 
	if(fif != FIF_UNKNOWN) { 
		printf("%s Format\n", FreeImage_GetFormatFromFIF(fif)); 
	} 
	printf(message); 
	printf(" ***\n"); 
} 
// In your main program … 
FreeImage_SetOutputMessage(FreeImageErrorHandler) 

FreeImage_Save

DLL_API  BOOL  DLL_CALLCONV  FreeImage_Save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const char *filename, int flags FI_DEFAULT(0));

Сохраняет на диск ранее загруженный в память графический файл.

На входе принимает "тип файла" (значение типа FREE_IMAGE_FORMAT), "графический файл, загруженный в память" (указатель на значение типа FIBITMAP), строку - путь, по которому будет сохранён на диске графический файл, опции сохранения файла (по умолчанию ноль). Возвращает TRUE / FALSE (успешно/не успешно). Если файл уже существует, он будет перезаписан.


FreeImage_Unload

DLL_API  void  DLL_CALLCONV  FreeImage_Unload(FIBITMAP *dib);

Удаляет из памяти ранее загруженный туда графический файл.

На входе принимает "графический файл, загруженный в память" (указатель на значение типа FIBITMAP).

warning.gif (1787 bytes) Вам всегда необходимо вызывать эту функцию по окончании работы с файлом, иначе будет утечка памяти.

Приложение

Для удобства работы в библиотеке FreeImage используются "обобщённые" типы графических данных. Это даёт "дополнительный слой абстракции" - т.е. возможность не менять исходные коды, когда меняются стандарты и представления графических файлов, появляются новые форматы, исчезают старые и т.п.

Для этого используется специальный параметр - перечисление типа FREE_IMAGE_FORMAT. Это перечисление определено в заголовочном файле FREEIMAGE.H. Пока доступны следующие его значения:

Таблица 1: Предопределённые идентификаторы типа FREE_IMAGE_FORMAT.

FIF Description
FIF_UNKNOWN Unknown format (returned value only, never use it as input value)
FIF_BMP Windows or OS/2 Bitmap File (*.BMP)
FIF_CUT Dr. Halo (*.CUT)
FIF_DDS DirectDraw Surface (*.DDS)
FIF_FAXG3 Raw Fax format CCITT G3 (*.G3)
FIF_GIF Graphics Interchange Format (*.GIF)
FIF_HDR High Dynamic Range (*.HDR)
FIF_ICO Windows Icon (*.ICO)
FIF_IFF Amiga IFF (*.IFF, *.LBM)
FIF_JNG JPEG Network Graphics (*.JNG)
FIF_JPEG Independent JPEG Group (*.JPG, *.JIF, *.JPEG, *.JPE)
FIF_KOALA Commodore 64 Koala format (*.KOA)
FIF_MNG Multiple Network Graphics (*.MNG)
FIF_PBM Portable Bitmap (ASCII) (*.PBM)
FIF_PBMRAW Portable Bitmap (BINARY) (*.PBM)
FIF_PCD Kodak PhotoCD (*.PCD)
FIF_PCX Zsoft Paintbrush PCX bitmap format (*.PCX)
FIF_PGM Portable Graymap (ASCII) (*.PGM)
FIF_PGMRAW Portable Graymap (BINARY) (*.PGM)
FIF_PNG Portable Network Graphics (*.PNG)
FIF_PPM Portable Pixelmap (ASCII) (*.PPM)
FIF_PPMRAW Portable Pixelmap (BINARY) (*.PPM)
FIF_PSD Adobe Photoshop (*.PSD)
FIF_RAS Sun Rasterfile (*.RAS)
FIF_SGI Silicon Graphics SGI image format (*.SGI)
FIF_TARGA Truevision Targa files (*.TGA, *.TARGA)
FIF_TIFF Tagged Image File Format (*.TIF, *.TIFF)
FIF_WBMP Wireless Bitmap (*.WBMP)
FIF_XBM X11 Bitmap Format (*.XBM)
FIF_XPM X11 Pixmap Format (*.XPM)

В дополнение к существующим, Вы можете определить свой тип графических данных - если Вы создали обработчик для работы с ним.


Hosted by uCoz