-
January 24th, 2004, 12:25 PM
#1
question (tiff)
open tiff 16bit b&w file and read line-line...:
unsigned long *scanin =
(unsigned long *)GlobalAlloc(GMEM_FIXED,
(w * h * sizeof (unsigned long)));
unsigned long * dest = (unsigned long *)m_dib->GetBits();
for (int row = 0; row < h; row++) {
TIFFReadScanline(tiff, scanin, row, 0);
void * ptr_dest = dest + row * dibwidth;
memcpy(ptr_dest,scanin,w*sizeof(int));
}
draw...
CClientDC dc(this);
CPoint sp = GetScrollPosition();
dib->Draw(&dc,sp.x,sp.y);
Q:
with above code, to open 16bit b&W image, i get colored noisy image.
how to get nice smooth b&w?.
-
January 24th, 2004, 01:46 PM
#2
I think it's easier if you use TIFFReadRGBAImage to read RGBA in temporary buffer, then apply correct scanline padding, then blit to screen.
-
January 24th, 2004, 04:16 PM
#3
question
seems like TIFFReadRGBAImage does not work with 16 bit images.
-
January 25th, 2004, 03:14 AM
#4
I hope you mean 16 bit grayscale? not black and white?
TIFFReadRGBAImage does support 16 bit grayscale images, I use the following code to open all kinds of TIFF files. It's just a copy paste of a project of mine, named MediaBrowser. Download MediaBrowser and try to open your tiff file with it. If MediaBrowser cannot open it, please send that tiff to me.
Code:
uint32 nWidth, nHeight;
for (int i=0; i<m_iNumOfImages; i++)
{
TIFFSetDirectory(tif, (tdir_t)i);
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &nWidth);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &nHeight);
uint32 nBitsPerSample = 0;
uint32 nSamplesPerPixel = 0;
float fXResolution = 96.0f;
float fYResolution = 96.0f;
uint32 nResolutionUnit = 1;
TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &nBitsPerSample);
TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &nSamplesPerPixel);
TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &nResolutionUnit);
TIFFGetField(tif, TIFFTAG_XRESOLUTION, &fXResolution);
TIFFGetField(tif, TIFFTAG_YRESOLUTION, &fYResolution);
if (RESUNIT_CENTIMETER == nResolutionUnit)
{
fXResolution *= 2.54f;
fYResolution *= 2.54f;
}
uint32 nXResolution = (uint32)(fXResolution+0.5);
uint32 nYResolution = (uint32)(fYResolution+0.5);
m_nBPP[i] = nBitsPerSample * nSamplesPerPixel;
uint32 npixels = nWidth * nHeight;
uint32* pTempBuffer = (uint32*)_TIFFmalloc(npixels * sizeof (uint32));
uint32 *sampleinfo, extrasamples, si;
if (nSamplesPerPixel == 4) {
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo);
if (!sampleinfo || sampleinfo[0] == EXTRASAMPLE_UNSPECIFIED) {
si = EXTRASAMPLE_ASSOCALPHA;
TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, &si);
}
}
if (pTempBuffer != NULL) {
if (!TIFFReadRGBAImage(tif, nWidth, nHeight, pTempBuffer, 1)) {
TIFFClose(tif);
_TIFFfree(pTempBuffer);
Cleanup();
return ExaImage::exaError;
}
}
else
{
Cleanup();
return ExaImage::exaError;
}
//TIFFClose(tif);
uint32 row_stride = DIB_WIDTHBYTES(nWidth * 24);
m_buffer[i] = (unsigned char*)malloc(row_stride * nHeight);
m_alpha[i] = (unsigned char*)malloc(nWidth * nHeight);
int j=0;
unsigned char* pBuf = m_buffer[i];
for (unsigned int y=0;y<nHeight;y++) {
j=0;
for (unsigned int x=0;x<nWidth;x++) {
pBuf[j++]=(unsigned char)TIFFGetB(pTempBuffer[y*nWidth+x]);
pBuf[j++]=(unsigned char)TIFFGetG(pTempBuffer[y*nWidth+x]);
pBuf[j++]=(unsigned char)TIFFGetR(pTempBuffer[y*nWidth+x]);
}
pBuf += row_stride;
}
j=0;
for (unsigned int y=0;y<nHeight;y++) {
for (unsigned int x=0;x<nWidth;x++) {
(*(m_alpha+i))[j]=(unsigned char)TIFFGetA(pTempBuffer[y*nWidth+x]);
if ((*(m_alpha+i))[j] != 255)
m_bContainsAlpha[i] = TRUE;
j++;
}
}
_TIFFfree(pTempBuffer);
m_bmpInfo[i] = (BITMAPINFO*)calloc(1,sizeof(BITMAPINFO));
m_bmpInfo[i]->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_bmpInfo[i]->bmiHeader.biWidth = nWidth;
m_bmpInfo[i]->bmiHeader.biHeight = nHeight;
m_bmpInfo[i]->bmiHeader.biPlanes = 1;
m_bmpInfo[i]->bmiHeader.biBitCount = (WORD)24;
m_bmpInfo[i]->bmiHeader.biCompression = BI_RGB;
m_bmpInfo[i]->bmiHeader.biSizeImage = 0;
m_bmpInfo[i]->bmiHeader.biXPelsPerMeter = (LONG)(DPI_TO_PELSPERMETER(nXResolution)+0.5);
m_bmpInfo[i]->bmiHeader.biYPelsPerMeter = (LONG)(DPI_TO_PELSPERMETER(nYResolution)+0.5);
m_bmpInfo[i]->bmiHeader.biClrUsed = 0;
m_bmpInfo[i]->bmiHeader.biClrImportant = 0;
m_bImageOpened = TRUE;
}
TIFFClose(tif);
-
January 25th, 2004, 12:50 PM
#5
could i ask?:
what are the declaration for i, m_nBPP[i], DIB_WIDTHBYTES in :
TIFFSetDirectory(tif, (tdir_t)i);
m_nBPP[i];
uint32 row_stride = DIB_WIDTHBYTES(nWidth * 24); <<i get DIB_WIDTHBYTES undeclared
what do i pass to StretchDIBits as image buffer for display?.
maybe, pTempBuffer..?..?
-
January 26th, 2004, 06:48 AM
#6
Originally posted by celtics
could i ask?:
what are the declaration for i, m_nBPP[i], DIB_WIDTHBYTES in :
TIFFSetDirectory(tif, (tdir_t)i);
m_nBPP[i];
i is an integer defined in the for loop (the second line).
m_nBPP[i] is just an array that I use to store the number of bits per pixel for each image in the tiff file. You can just drop this.
DIB_WIDTHBYTES is defined as:
Code:
#define DIB_WIDTHBYTES(bits) ((((bits) + 31)>>5)<<2)
uint32 row_stride = DIB_WIDTHBYTES(nWidth * 24); <<i get DIB_WIDTHBYTES undeclared
what do i pass to StretchDIBits as image buffer for display?.
maybe, pTempBuffer..?..?
I use something like:
Code:
::StretchDIBits(hDC,x,y,cx,cy,0,0,GetWidth(iImageNum),GetHeight(iImageNum), m_buffer[iImageNum], m_bmpInfo[iImageNum],DIB_RGB_COLORS,SRCCOPY);
iImageNum is index of the image you want to render.
m_buffer contains the bits of the image.
m_bmpInfo is also filled by the code I posted in my previous post.
-
January 6th, 2011, 02:01 AM
#7
Re: question (tiff)
Hi Marc, i wants to render a multipage TIFF file in a client window(win32), may i know the data type of m_buffer and m_alpha when i declared as a unsigned char* i got error.
-
January 6th, 2011, 07:24 AM
#8
Re: question (tiff)
I don't have the code in front of me, but I'm pretty sure I'm defining them as unsigned chars.
Can you post some code.
-
January 22nd, 2011, 07:44 AM
#9
Re: question (tiff)
Thanks marc for you suggesstion.
Last edited by lamrinraj; January 22nd, 2011 at 07:57 AM.
-
January 22nd, 2011, 07:56 AM
#10
Re: question (tiff)
/****************************************************************************/
hi marc, here's i posted my code, my objective is to render multipage tiff image inside the client area when i try to load very first page even i couldn't can you correct the code and suggest some idea to render. i don't have enough knowledge in TIFF and graphics function too... I'm still trying and expect your suggesstions.
Thanks
Code:
/****************************************************************************/
#include <windows.h>
#include <iostream.h>
#include <tiffio.h>
#include <tchar.h>
#include <fstream.h>
#include <string.h>
#include <stdio.h>
#include "tiffiop.h"
#define MAX 1024
#define DIB_WIDTHBYTES(bits) ((((bits) + 31)>>5)<<2)
static TCHAR szWindowClass[] = _T("win32app");
static TCHAR szTitle[] = _T("TIFF Viewer");
HWND hWnd;
#define ID_FILE_OPEN 300
#define ID_STUFF_GO 301
typedef struct CxImageInfo {
DWORD dwEffWidth; //DWORD aligned scan line width
BYTE* pImage; //THE IMAGE BITS
DWORD dwType; //original image format
char szLastError[256]; //debugging
long nProgress; //monitor
long nEscape; //escape
long nBkgndIndex; //used for GIF, PNG, MNG
BYTE nQuality; //used for JPEG
long nFrame; //used for TIF, GIF, MNG : actual frame
long nNumFrames; //used for TIF, GIF, MNG : total number of frames
DWORD dwFrameDelay; //used for GIF, MNG
long xDPI; //horizontal resolution
long yDPI; //vertical resolution
BYTE nAlphaMax; //max opacity (fade)
bool bAlphaPaletteEnabled; //true if alpha values in the palette are enabled.
bool bEnabled; //enables the painting functions
long xOffset;
long yOffset;
DWORD dwEncodeOption; //for GIF, TIF : 0=def.1=unc,2=fax3,3=fax4,4=pack,5=jpg
BYTE last_c_index;
bool last_c_isvalid;
long nNumLayers;
DWORD dwFlags;
};
struct CxImageInfo info;
void ImageOpen(HWND hWnd);
TIFF *tiff;
uint32 *raster;
uint32 width=NULL;
uint32 height=NULL;
char Buffer[256];
int hFileHandle;
uint32 x;
uint32 y;
uint16 bitspersample; //Bits Per Sample
uint16 samplesperpixel; //Samples Per Pixel
uint32 rowsperstrip; //Rows Per Strip
uint16 photometric; //Photometric Value
uint16 compression; //Compression Type
uint16 orientation; //Orientation
uint16 planarConfiguration; //Planar Info
uint16 extraSamples; //Extra Samples
uint16 photo;
uint16 bps;
uint16 spp;
uint16 res_unit; //Resolution Measurement
uint16 fillorder;
float resolution, offset;
int stripMax, stripCount;
BOOL isRGB;
BYTE *bits;
BYTE *bits2;
long xOffset;
long yOffset;
long no_of_frames;
BITMAPINFOHEADER head;
char filename[]="";
char Temp_Buffer[1024];
char *Temp="";
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL,_T("Call to RegisterClassEx failed!"),_T("Win32 Guided Tour"),NULL);
return 1;
}
hInst = hInstance;
hWnd = CreateWindow(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
if (!hWnd)
{
MessageBox(NULL,_T("Call to CreateWindow failed!"),_T("Error"),MB_ICONERROR);
return 1;
}
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR print_msg[] = _T("TIFF Viewer Interface");
int wmId, wmEvent;
HMENU hMenu, hSubMenu;
// CDC *m_pdc;
switch (message)
{
case WM_CREATE:
hMenu = CreateMenu();
hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_FILE_OPEN, "O&pen");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");
SetMenu(hWnd, hMenu);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch(wmId){
case ID_FILE_OPEN:
ImageOpen(hWnd);
break;
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc,5, 5,print_msg, _tcslen(print_msg));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
void ImageOpen(HWND hWnd){
struct RGB
{
BYTE Blue;
BYTE Green;
BYTE Red;
};
TCHAR Temp_Buffer[MAX]="";
char FileName[1000]="";
int m_nBPP[MAX];
uint32 nBitsPerSample = 0;
uint32 nSamplesPerPixel = 0;
float fXResolution = 96.0f;
float fYResolution = 96.0f;
uint32 nResolutionUnit = 1;
OPENFILENAME file;
BOOL bret;
memset(&file,0,sizeof(file));
file.lStructSize = sizeof(file);
file.Flags = OFN_HIDEREADONLY;
file.lpstrFile=FileName;
file.nMaxFile=1000;
file.lpstrFilter="TIFF Files(*.tif,*.tiff)";
bret=GetOpenFileName(&file);
if(bret==FALSE){
MessageBox(NULL,"No files selected","Notifier",NULL);
}
tiff=TIFFOpen(FileName, "rb");
if(!tiff){
MessageBox(hWnd,_T("Not a Valid TIFF File"),_T("Notifier"),NULL);
exit(1);
}
MessageBox(hWnd,_T("Read Okay - a Valid TIFF File"),_T("Notifier"),NULL);
TIFFGetField(tiff,TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(tiff,TIFFTAG_IMAGELENGTH, &height);
TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
TIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planarConfiguration);
TIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extraSamples);
if((width>0)&&(height>0)){
sprintf(Temp_Buffer,"The width is %d Height is %d Samples per Pixel %d Photometric %d",width,height,samplesperpixel,photometric);
MessageBox(hWnd,Temp_Buffer,"Notifier",NULL);
}
if((TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitspersample) == 0) || (bitspersample != 1)){
MessageBox(hWnd,"Either undefined or unsupported number of bits per sample","Notifier",NULL);
}
int i=0;
int m_num_items = TIFFNumberOfDirectories(tiff);
sprintf(Temp_Buffer,"The pages are %d",m_num_items);
MessageBox(hWnd,Temp_Buffer,"Pages",NULL);
/*************************************************/
if (m_num_items > 0)
{
for (int i=0;i<m_num_items;i++){
tdir_t d = (tdir_t)i;
TIFFSetDirectory(tiff,d);
int w=0, h=0;
int bpp = 0;
char name[256];
memset(name,0,(size_t)256);
sprintf(name,"image%d",i);
TIFFGetField(tiff,TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(tiff,TIFFTAG_IMAGELENGTH, &h);
TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bpp);
TIFFGetFieldDefaulted(tiff, TIFFTAG_SAMPLESPERPIXEL, &nSamplesPerPixel);
TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &nResolutionUnit);
TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &fXResolution);
TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &fYResolution);
sprintf(Temp_Buffer,"The width is %d, Height is %d , BPP is %d, SPP is %d, Resolution unit %d, X-Resolution %d, Y-Resolution %d ",w,h,bpp,nSamplesPerPixel,nResolutionUnit,fXResolution,fYResolution);
MessageBox(hWnd,Temp_Buffer,"Properties",NULL);
}
int last_dir=TIFFCurrentDirectory(tiff);
if(last_dir){
MessageBox(hWnd,"Last Dir Reached","Dir Info",NULL);
}
}
/**************************************************/
TIFFSetDirectory(tiff, (tdir_t)i);
TIFFGetField(tiff,TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(tiff,TIFFTAG_IMAGELENGTH, &height);
TIFFGetFieldDefaulted(tiff, TIFFTAG_BITSPERSAMPLE, &nBitsPerSample);
TIFFGetFieldDefaulted(tiff, TIFFTAG_SAMPLESPERPIXEL, &nSamplesPerPixel);
TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &nResolutionUnit);
TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &fXResolution);
TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &fYResolution);
uint32 nXResolution = (uint32)(fXResolution+0.5);
uint32 nYResolution = (uint32)(fYResolution+0.5);
m_nBPP[i] = nBitsPerSample * nSamplesPerPixel;
uint32 npixels = width * height;
uint32* pTempBuffer = (uint32*)_TIFFmalloc(npixels * sizeof (uint32));
uint32 *sampleinfo, extrasamples, si;
if (nSamplesPerPixel == 4) {
TIFFGetFieldDefaulted(tiff, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo);
if (!sampleinfo || sampleinfo[0] == EXTRASAMPLE_UNSPECIFIED){
si = EXTRASAMPLE_ASSOCALPHA;
TIFFSetField(tiff, TIFFTAG_EXTRASAMPLES, 1, &si);
}
}
if (pTempBuffer != NULL) {
if (!TIFFReadRGBAImage(tiff, width, height, pTempBuffer, 1)) {
TIFFClose(tiff);
_TIFFfree(pTempBuffer);
}
}
unsigned int y=0;
// unsigned char* *m_buffer;
// unsigned char* *m_alpha;
// unsigned char* *m_bContainsAlpha;
uint32 row_stride = DIB_WIDTHBYTES(width * 24);
unsigned char *m_buffer;
unsigned char *m_alpha;
//m_buffer[i] = (unsigned char*)malloc(row_stride * height);
//m_alpha[i] = (unsigned char*)malloc(width * height);
m_buffer = (unsigned char*)malloc(row_stride * height);
m_alpha = (unsigned char*)malloc(width * height);
int j=0;
unsigned char* pBuf = m_buffer;
for (y=0;y<height;y++) {
j=0;
for (unsigned int x=0;x<width;x++) {
pBuf[j++]=(unsigned char)TIFFGetB(pTempBuffer[y*width+x]);
pBuf[j++]=(unsigned char)TIFFGetG(pTempBuffer[y*width+x]);
pBuf[j++]=(unsigned char)TIFFGetR(pTempBuffer[y*width+x]);
}
pBuf += row_stride;
}
j=0;
for (y=0;y<height;y++) {
for (unsigned int x=0;x<width;x++) {
(*(m_alpha+i))=(unsigned char)TIFFGetA(pTempBuffer[y*width+x]);
if ((*(m_alpha+i)) != 255)
// m_bContainsAlpha[i] = TRUE;
j++;
}
}
_TIFFfree(pTempBuffer);
BITMAPINFOHEADER bi_hdr;
BITMAPINFO bi_info;
void *pBits;
bi_hdr.biSize=sizeof(BITMAPINFOHEADER);
bi_hdr.biWidth=width;
bi_hdr.biHeight = height;
bi_hdr.biPlanes = 1;
bi_hdr.biBitCount = (WORD)24;
bi_hdr.biCompression = BI_RGB;
bi_hdr.biSizeImage = 0;
bi_hdr.biXPelsPerMeter = 0;
bi_hdr.biYPelsPerMeter = 0;
bi_hdr.biClrUsed = 0;
bi_hdr.biClrImportant = 0;
HDC hDC=CreateCompatibleDC(NULL);
HBITMAP hBmp=CreateDIBSection(NULL,(BITMAPINFO*)&bi_hdr,DIB_RGB_COLORS,&pBits,NULL,0);
if(hBmp){
MessageBox(hWnd,"CreateDIBSection() Success","Info",NULL);
}
HDC hMemDC=CreateCompatibleDC(hDC);
HBITMAP hBmpOld=(HBITMAP)SelectObject(hMemDC,hBmp);
BitBlt(hDC,0,0,bi_hdr.biWidth,bi_hdr.biHeight,hMemDC,0,0,SRCCOPY);
/*
bool m_bImageOpened = TRUE;
HDC hDC;
hDC=GetDC(hWnd);
::StretchDIBits(hDC,0,0,10,20,0,0,bi.biWidth,bi.biHeight,
(void *)m_buffer,
,DIB_RGB_COLORS,SRCCOPY);
ReleaseDC(hWnd,hDC);
*/
}
Last edited by Marc G; January 22nd, 2011 at 08:04 AM.
Reason: Added code tags
-
January 22nd, 2011, 08:16 AM
#11
Re: question (tiff)
I just checked my MediaBrowser source and I have:
Code:
// Array of the images
unsigned char** m_buffer;
// Array of the alpha channels of the images
unsigned char** m_alpha;
So there you have my data types.
Unfortunately, I don't have time right now to check your code.
-
January 22nd, 2011, 08:25 AM
#12
Re: question (tiff)
Thanks Marc, i thought i'm strucking around DIBSection and BitBlt Function possible check whether i am sending proper DC data to BitBlt or not.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|