You are not logged in.
Pages: 1
Hi,
I just took a look at the repository and noticed that the code you posted missed the constructor override for TTiffImage and thus the initialization code of the fActivePageIndex variable.
Ryan.
Sorry for the mess....but I wanted to post back to the group before I moved on and forgot that I had done this.
This is based off of the latest version of the syngdiplus.pas file found in the source code repository.
// ****************************************
// Interface Section Code
// ****************************************
// ****************************************
// add to the private section of the TGDIPlus class
// ****************************************
GetFrameCount: function (image: THandle; dimensionID: PGUID; var count: UINT): TGdipStatus; stdcall;
SelectActiveFrame: function (image: THandle; dimensionID: PGUID; frameIndex: UINT): TGdipStatus; stdcall;
// ****************************************
// Replace the existing declaration of TTiffImage
// ****************************************
TTiffImage = class(TSynPicture)
private
fActivePage : integer;
protected
//Selects the active frame/page for the TIFF
procedure SelectPage(index:integer); //rjm
public
constructor Create; override; //rjm
//Extract a page from the TIFF and assign it to a bitmap
procedure ExtractPage(index:integer; wBMP:TBitmap); //rjm
//Retrieve the number of pages in the TIFF file
function GetPageCount:integer;
//Default Frame/Page Index is 0
property ActivePageIndex : integer read fActivePage write SelectPage;
end;
// ****************************************
// Implementation Section Code
// ****************************************
// ****************************************
// add to the top of the implementaion section
// ****************************************
const
//---------------------------------------------------------------------------
// Predefined multi-frame dimension IDs
//---------------------------------------------------------------------------
FrameDimensionPage : TGUID = '{7462dc86-6180-4c7e-8e3f-ee7333a7a483}';
{$EXTERNALSYM FrameDimensionPage}
// ****************************************
// Replace the existing declaration of GdiPProcNames
// ****************************************
const GdiPProcNames: array[0..18{$ifdef USEDPI}+1{$endif}
{$ifdef USEENCODERS}+2{$endif}] of PChar =
('GdiplusStartup','GdiplusShutdown',
'GdipDeleteGraphics','GdipCreateFromHDC',
'GdipLoadImageFromStream','GdipLoadImageFromFile',
'GdipDrawImageRectI','GdipDrawImageRectRectI',
{$ifdef USEDPI} 'GdipDrawImageI', {$endif}
'GdipDisposeImage', 'GdipGetImageRawFormat',
'GdipGetImageWidth','GdipGetImageHeight','GdipSaveImageToStream',
{$ifdef USEENCODERS} 'GdipGetImageEncodersSize','GdipGetImageEncoders', {$endif}
'GdipCreateBitmapFromHBITMAP','GdipCreateBitmapFromGdiDib','GdipBitmapSetResolution',
'GdipImageGetFrameCount', 'GdipImageSelectActiveFrame', // <--new function names //rjm
nil);
// ****************************************
// add to the bottom of the unit above the initialization section
// ****************************************
{ TTiffImage }
//rjm
function TTiffImage.GetPageCount: integer;
var
wCount : UINT;
begin
if (fImage<>0) then
begin
Gdip.GetFrameCount(fImage, @FrameDimensionPage, wCount);
result := wCount;
end
else
result := 0;
end;
//rjm
procedure TTiffImage.SelectPage(index: integer);
var
wFrames : integer;
begin
wFrames := GetPageCount;
if (wFrames > 0) and ((index >= 0) and (index < wFrames)) then
begin
Gdip.SelectActiveFrame(fImage, @FrameDimensionPage, index);
fActivePage := index;
end
else
raise ERangeError.Create('Invalid Page Index');
end;
//rjm
constructor TTiffImage.Create;
begin
inherited;
fActivePage := 0;
end;
//rjm
procedure TTiffImage.ExtractPage(index: integer; wBMP:TBitmap);
var
wFrames : integer;
wStrm : TMemoryStream;
begin
wFrames := GetPageCount;
if (wFrames > 0) and ((index >= 0) and (index < wFrames)) then
begin
Try
Gdip.SelectActiveFrame(fImage, @FrameDimensionPage, index);
wStrm := TMemoryStream.Create;
try
SaveAs(wstrm,gptBMP);
wStrm.Position := 0;
wBmp.LoadFromStream(wStrm);
finally
wStrm.Free;
end;
finally
Gdip.SelectActiveFrame(fImage, @FrameDimensionPage, fActivePage);
end;
end
else
raise ERangeError.Create('Invalid Page Index');
end;
Thanks for a great library.
Here are a two changes that I've made for my use that I think other might find usefull.
procedure TSynPicture.AssignTo(Dest: TPersistent);
begin
//This currently only handles TBitmap but could/should be extended for other TGraphic Classes
if Dest is TBitmap then
begin
TBitmap(Dest).Assign(Self.ToBitmap);
//This block is not really necessary. I've left it here for the completeness of my change
if TBitmap(Dest).PixelFormat = pfDevice then
begin
if Self is TPngImage then
TBitmap(Dest).PixelFormat := pf32bit //Possibly Alpha Transaparancy
else if Self is TGifImage then
TBitmap(Dest).PixelFormat := pf8bit //Palletted Image
else //TTiffImage, TJpegImage
TBitmap(Dest).PixelFormat := pf24bit; //Everything else
end;
end
else
Inherited;
end;
The above code allows for the common usage of assigning a TGraphic class to another TGraphic Class
For Example:
var
wBMP : TBitmap;
begin
wBMP := TBitmap.create;
try
...
//wPic is a TImage, and then Graphic is a TSynPicture descendant class (TTiffImage for example )
wBMP.Assign( wPic.Picture.Graphic );
...
Finally
wBMP.free;
end;
end;
The other change is in the ability to Define registering only specific TSynPicture classes
The following block should go under the NOTSYNPICTIREREGISTER define at the top of the file
{ if NOTSYNPICTUREREGISTER is not defined then the following has no effect }
{$define RegisterIndividualFormats}
{if RegisterIndividualFormats is not defined then all of the file formats are registered }
{ if RegisterIndividualFormats is defined then the following defines will register the appropriate TGraphic classes }
{$define RegisterTIFF}
{.$define RegisterJPEG}
{.$define RegisterPNG}
{$define RegisterGIF}
The following block should replace the If GetClass('TTiffImage') = nil then block of code in then RegisterPictures method
{$ifdef RegisterIndividualFormats}
{$ifdef RegisterJPEG}
RegisterClass(TJpegImage);
TPicture.RegisterFileFormat(PicturesExt[0], PictureName(PictureClasses[0]), PictureClasses[0]);
TPicture.RegisterFileFormat(PicturesExt[1], PictureName(PictureClasses[1]), PictureClasses[1]);
{$endif}
{$ifdef RegisterPNG}
RegisterClass(TPngImage);
TPicture.RegisterFileFormat(PicturesExt[2], PictureName(PictureClasses[2]), PictureClasses[2]);
{$endif}
{$ifdef RegisterGIF}
RegisterClass(TGifImage);
TPicture.RegisterFileFormat(PicturesExt[3], PictureName(PictureClasses[3]), PictureClasses[3]);
{$endif}
{$ifdef RegisterTIFF}
RegisterClass(TTiffImage);
TPicture.RegisterFileFormat(PicturesExt[4], PictureName(PictureClasses[4]), PictureClasses[4]);
TPicture.RegisterFileFormat(PicturesExt[5], PictureName(PictureClasses[5]), PictureClasses[5]);
{$endif}
{$else}
// register JPG and PNG pictures as TGraphic
if GetClass('TTiffImage')=nil then
begin
RegisterClass(TJpegImage);
RegisterClass(TPngImage);
RegisterClass(TGifImage);
RegisterClass(TTiffImage);
for i := 0 to high(PicturesExt) do
TPicture.RegisterFileFormat(PicturesExt[i],
PictureName(PictureClasses[i]),PictureClasses[i]);
end;
{$endif}
Hopefully other people find this useful.
Ryan.
Pages: 1