Перейти к содержимому
Compvision.ru

Recommended Posts

Всем привет! Дайте совет - какую библиотеку юзать для работы с TIFF-файлами? Задача состоит только в получении самих данных изображения (без всяких тегов и прочего). Есть конечно вариант - использовать GDI+, но я не нашел нормального руководства использования GDI+ в C++ :(

Данные впоследствии будут перенесены в OpenCV ... (да я знаю, что OpenCV открывает TIFF-файлы, только вот TIFF размером в гигабайт он не осилит)

p.s. от примера не отказался бы.

Спасибо за внимание!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

libtiff http://www.libtiff.org/libtiff.html , которая вроде как и используется в OpenCV.

#include "tiffio.h"

main()

{

    TIFF* tif = TIFFOpen("foo.tif", "r");

    ... do stuff ...

    TIFFClose(tif);

}

как то так. только TIFF* потом надо переделывать в IplImage*.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

libtiff http://www.libtiff.org/libtiff.html , которая вроде как и используется в OpenCV.

#include "tiffio.h"

main()

{

    TIFF* tif = TIFFOpen("foo.tif", "r");

    ... do stuff ...

    TIFFClose(tif);

}
как то так. только TIFF* потом надо переделывать в IplImage*.
Могу сказать,что я юзал именно эту библиотеку и впечатления мягко говоря паршивые остались ... Особенно документация "радует" :( Вот что "наваял" я пару-тройку дней назад (до создания этой темы) - может кому и пригодится:

#include "stdafx.h"

#include "tiffio.h"

#include "windows.h"


class Tiffer

{

	public: struct TIFF_INFO

	{

		TIFF *imageTiff;

		wchar_t *imagePath;


		int imageWidth;

		int imageHeight;

		int imageDepth;

		int numOfImgChannels;


		bool isWriting;

	};


	TIFF_INFO TiffInfo;


	public: int OpenTiffImage(wchar_t *path, char *filemode)

	{

		TiffInfo.imagePath = path;

		//MessageBoxW(0, (LPCWSTR)TiffInfo.tiffPath, L"OLOLO", 0);


		char *chPath = new char[wcslen(TiffInfo.imagePath)];

		wcstombs(chPath, TiffInfo.imagePath, 255); // конвертируем из wchar_t* в char*


		TiffInfo.imageTiff = TIFFOpen(chPath, filemode);


		return 0;

	}


	public: void SetTiffImageInfo(int imageWidth, int imageHeight, int imageDepth, int numOfImgChannels)

	{

		TiffInfo.imageWidth = imageWidth;

		TiffInfo.imageHeight = imageHeight;

		TiffInfo.imageDepth = imageDepth;

		TiffInfo.numOfImgChannels = numOfImgChannels;


		// различные свойства нового TIFF

		TIFFSetField(TiffInfo.imageTiff, TIFFTAG_IMAGEWIDTH, TiffInfo.imageWidth);

		TIFFSetField(TiffInfo.imageTiff, TIFFTAG_IMAGELENGTH, TiffInfo.imageHeight);

		TIFFSetField(TiffInfo.imageTiff, TIFFTAG_SAMPLESPERPIXEL, TiffInfo.numOfImgChannels);

		TIFFSetField(TiffInfo.imageTiff, TIFFTAG_BITSPERSAMPLE, TiffInfo.imageDepth);

		TIFFSetField(TiffInfo.imageTiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);

		TIFFSetField(TiffInfo.imageTiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);

		TIFFSetField(TiffInfo.imageTiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);

	}


	public: void GetTiffImageInfo()

	{

		TIFFGetField(TiffInfo.imageTiff, TIFFTAG_IMAGEWIDTH, &TiffInfo.imageWidth);

		TIFFGetField(TiffInfo.imageTiff, TIFFTAG_IMAGELENGTH, &TiffInfo.imageHeight);

		TIFFGetField(TiffInfo.imageTiff, TIFFTAG_SAMPLESPERPIXEL, &TiffInfo.numOfImgChannels);

		TIFFGetField(TiffInfo.imageTiff, TIFFTAG_BITSPERSAMPLE, &TiffInfo.imageDepth);

	}


	public: int WriteTiffData(int rowNumber, byte *data)

	{

		tsize_t lineBytes = TiffInfo.numOfImgChannels * TiffInfo.imageWidth;


		byte *buffer = NULL; // буфер, содержащий строку пикселей, записываемую в файл


		// выделение памяти для текущей строки пикселей ========================================================

		int lineSize = TIFFScanlineSize(TiffInfo.imageTiff);

		if (lineSize == lineBytes) buffer = (byte*)_TIFFmalloc(lineBytes);

		else buffer = (byte*)_TIFFmalloc(lineSize);

		// =====================================================================================================


		// указываем размер полосы = размеру строки пикселей *****************************************************************

		if(!TiffInfo.isWriting)

		{

			int defaultStripSize = TIFFDefaultStripSize(TiffInfo.imageTiff, TiffInfo.imageWidth * TiffInfo.numOfImgChannels);

			TIFFSetField(TiffInfo.imageTiff, TIFFTAG_ROWSPERSTRIP, defaultStripSize);

			TiffInfo.isWriting = true;

		}

		// *******************************************************************************************************************


		// записываем в файл по одной строке за раз

		/*for (uint32 row = 0; row < TiffInfo.imageHeight; row++)

		{

			//int sz = (TiffInfo.imageHeight-row-1)*lineBytes; // запись наоборот

			int sz = row * lineBytes;


			memcpy(buffer, &data[sz], lineBytes);


			// запись

			//if (TIFFWriteScanline(TiffInfo.imageTiff, buffer, row, 0) < 0) break;


			for(int i = 0; i < 5; i++)

			{

				printf("%i\n", buffer[i]);

			}

		}*/


		//int sz = rowNumber * lineBytes;

		//memcpy(buffer, &data, lineBytes);


		/*for(int i = 0; i < 15; i++)

		{

			printf("%i\n", buffer[i]);

		}*/


		TIFFWriteScanline(TiffInfo.imageTiff, data, rowNumber, 0);


		// очистка буферов

		if (buffer) _TIFFfree(buffer);


		return 0;

	}


	public: int ReadTiffData(int rowNumber, byte *&buffer)

	{

		tsize_t lineBytes = TiffInfo.numOfImgChannels * TiffInfo.imageWidth;


		// выделение памяти для буфера =========================================================================

		int lineSize = TIFFScanlineSize(TiffInfo.imageTiff);

		if (lineSize == lineBytes) buffer = (byte*)_TIFFmalloc(lineBytes);

		else buffer = (byte*)_TIFFmalloc(lineSize);

		// =====================================================================================================


		int scn = TIFFReadScanline(TiffInfo.imageTiff, buffer, rowNumber, 0);


		return 0;

	}


	public: void CloseTiffImage()

	{

		TIFFClose(TiffInfo.imageTiff);

	}


};


int _tmain()

{

	Tiffer *tiffReader = new Tiffer();

	Tiffer *tiffWriter = new Tiffer();


	tiffReader->OpenTiffImage(L"D:\\test2.tif", "r");

	tiffReader->GetTiffImageInfo();


	tiffWriter->OpenTiffImage(L"new.tif", "w");

	tiffWriter->SetTiffImageInfo(1000, 1000, 8, 3);


	for(int i=0;i<1000;i++)

	{

		byte *data = 0;

		tiffReader->ReadTiffData(i, data);


		tiffWriter->WriteTiffData(i, data);

	}


	tiffWriter->CloseTiffImage();

	tiffReader->CloseTiffImage();


	return 0;

}

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну что теперь открывает ~1Гб изображения?

я так понимаю что в opencv как раз проблема в том как он работает с памятью, а не в том что libtiff плохая.

зачем было писать все эти функции? там же вроде есть свои аналоги?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну что теперь открывает ~1Гб изображения?

я так понимаю что в opencv как раз проблема в том как он работает с памятью, а не в том что libtiff плохая.

зачем было писать все эти функции? там же вроде есть свои аналоги?

Нет, большие файлы нормально не копирует, да и библиотека эта убогая, я по-другому пробую. Из-за её убогости пришлось враппер кодить :)

А OpenCV так и не будет большие файлы открывать. Ну разве что если каким-то образом изменить CV_MAX_ALLOC_SIZE

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Всем, кто столкнется с этой проблемой, советую юзать GDAL :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×