Jump to content
Compvision.ru
TroyashkA

TIFF & C++

Recommended Posts

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

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

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

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

Share this post


Link to post
Share on other sites

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

#include "tiffio.h"

main()

{

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

    ... do stuff ...

    TIFFClose(tif);

}

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.

×