Difference between revisions of "fcl-image"
m (→Image formats: OSX -> macOS) |
|||
(29 intermediate revisions by 12 users not shown) | |||
Line 75: | Line 75: | ||
* '''fppixlcanv''' | * '''fppixlcanv''' | ||
** TPixelCanvas | ** TPixelCanvas | ||
− | * '''fpquantizer''' classes used to quantize images. | + | * '''fpquantizer''' classes used to quantize images. See [http://lazarus.freepascal.org/index.php/topic,13468.0] |
* '''freetype''' Encapsulating classes over freetype | * '''freetype''' Encapsulating classes over freetype | ||
* '''freetypeh''' Freetype header translation | * '''freetypeh''' Freetype header translation | ||
Line 85: | Line 85: | ||
* '''targacmn''' Targa fileformat records and types | * '''targacmn''' Targa fileformat records and types | ||
− | '''Readers and writers for various image formats''' | + | '''Readers and writers for various image formats''' reside in dedicated units: |
− | * '''fpreadbmp''' | + | * '''fpreadbmp''', '''fpwritebmp''': Reader and writer units for .bmp files |
− | * '''fpreadjpeg''' | + | * '''fpreadjpeg''', '''fpwritejpeg''': Reader and writer units for .jpeg/.jpg files |
− | * '''fpreadpcx''' | + | * '''fpreadpcx''', '''fprwritepcs''': Reader and writer units for .pcx files |
− | + | * '''fpreadpng''', '''fpwritepng''': Reader and writer units for .png files | |
− | * ''' | + | * '''fpreadpnm''', '''fpwritepnm''': Reader and writer units for .pnm files |
− | + | * '''fpreadtga''', '''fpwritetga''': Reader and writer units for .tga files | |
− | * ''' | + | * '''fpreadtiff''', '''fpwritetiff''': Reader and writer units for .tiff/.tif files |
− | + | * '''fpreadxpm''', '''fpwritexpm''': Reader and writer units for .xpm files | |
− | * ''' | ||
− | |||
− | * ''' | ||
− | |||
− | * ''' | ||
− | |||
'''INC files uses in fpcanvas''' | '''INC files uses in fpcanvas''' | ||
Line 119: | Line 113: | ||
* fppalette | * fppalette | ||
− | + | Demos | |
* drawing | * drawing | ||
Line 128: | Line 122: | ||
* fcl-image is written for maximal portability and maintainability and is quite slow. The main storage type is 16-bit RGBA, storing always 64-bit per pixel, and a function is called to get each pixel. | * fcl-image is written for maximal portability and maintainability and is quite slow. The main storage type is 16-bit RGBA, storing always 64-bit per pixel, and a function is called to get each pixel. | ||
* pngwriter doesn't implement automatic detection of filters, and thus is always "filter none" | * pngwriter doesn't implement automatic detection of filters, and thus is always "filter none" | ||
+ | * most writers don't autodetect what format to save. You must correctly set the relevant writer options ( see also [http://bugs.freepascal.org/view.php?id=17621 bug 17621]). | ||
+ | * the color format can be counter intuitive, read [http://www.mail-archive.com/fpc-devel@lists.freepascal.org/msg16506.html this thread] | ||
+ | * png only implements basic chunk types (idat,trns,plte,ihdr and iend). It e.g. can't handle chunks like pHYs,iCCP,gAMA,cHRM yet. ([http://bugs.freepascal.org/view.php?id=19209 bug 19209]). | ||
+ | |||
+ | == Image formats == | ||
+ | |||
+ | Here is a table with the correct class to use for each image format, as well as comparing to the LCL. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Format !! fcl-image reader unit !! fcl-image writer unit !! LCL class | ||
+ | |- | ||
+ | |Windows Bitmap. A very simple format, usually used without compression and without transparency, but it may also have them, although many applications don't support those extra features. (*.bmp)||fpreadbmp||fpwritebmp||TBitmap | ||
+ | |- | ||
+ | |A popular format for websites. It supports up to 8 bits per pixels, which are 256 distinct colors chosen from the 24-bit RGB color space. This limitation makes it unsuitable for complex images, but useful for simple graphics. The image is compressed without loss in quality and the format also supports animations. (*.gif)||fpreadgif||-||TGIFImage | ||
+ | |- | ||
+ | |The most popular format for websites, and an ISO standard since 1994. The format compressed the image but generates a small loss of quality. (*.jpeg, *.jpg)||fpreadjpeg||fpwritejpeg||TJpegImage | ||
+ | |- | ||
+ | |A format widely used in DOS applications, but now less popular. (*.pcx)||fpreadpcx||fpwritepcx||- | ||
+ | |- | ||
+ | |Portable Network Graphics. A popular format for it's efficient compression without quality loss. (*.png)||fpreadpng||fpwritepng||TPortableNetworkGraphic | ||
+ | |- | ||
+ | ||Supports the formats Portable BitMaps (*.pbm), Portable GrayMaps (*.pgm) and Portable PixMaps (*.ppm)||fpreadpnm||fpwritepnm||TPortableAnyMapGraphic | ||
+ | |- | ||
+ | |The default file format for Adobe Photoshop® (*.psd)||fpreadpsd||-||- | ||
+ | |- | ||
+ | |Called either Truevision TGA File Format or TARGA File Format, this is a compressed format commonly used in games. (*.tga, *.tpic)||fpreadtga||fpwritetga||- | ||
+ | |- | ||
+ | |Tagged Image File Format (TIFF), originally created to have a common image format for scanners. (*.tiff, *.tif). Controlled by Adobe®||fpreadtiff||fpwritetiff||TTiffImage | ||
+ | |- | ||
+ | |X PixMap, an image format used by the X Window System which stores the data in ASCII text. Is also used as an icon format in UNIX applications. (*.xpm)||fpreadxpm||fpwritexpm||TPixmap | ||
+ | |- | ||
+ | |X Window Dump file format. Used by the program xwd which generates screenshots in the X Window System. (*.xwd)||fpreadxwd||-||- | ||
+ | |- | ||
+ | |Windows Icon. Is a list of small bitmaps in various color depths and sizes, with transparency support and no compression. (*.ico)||-||-||TIcon | ||
+ | |- | ||
+ | |Windows Cursor. Exactly the same format as the Windows Icon, but with an extra field in the header for the cursor hotspot. (*.cur)||-||-||TCursorImage | ||
+ | |- | ||
+ | |macOS icon. List of small images in various sizes. (*.icns)||-||-||TIcnsIcon | ||
+ | |} | ||
+ | |||
+ | ===Tiff=== | ||
+ | |||
+ | Working features of the reader: | ||
+ | |||
+ | *Black and white/lineart/1 bit (FPC trunk only, not in FPC 2.6.x) | ||
+ | *Grayscale 8,16bit (optional alpha), | ||
+ | *RGB 8,16bit (optional alpha), | ||
+ | *Orientation, except for rotated orientation | ||
+ | *compression: packbits, LZW, deflate | ||
+ | *endian | ||
+ | *multiple images/multipage | ||
+ | *strips and tiles | ||
+ | *Sets properties in the image Extras properties, which is used by the writer, so that reading/writing keeps many common tags like Artist, Copyright, DateAndTime, HostComputer, ImageDescription, Maker, Model, Software, DocumentName, XResolution, YResolution, Orientation, bit depts, page name, isThumbnail. | ||
+ | |||
+ | Here is an incomplete list of open / not yet implemented features of the reader: | ||
+ | |||
+ | *Compression: jpeg, CCITT Group 3, CCITT Group 4 | ||
+ | *PlanarConfiguration 2 | ||
+ | *ColorMap | ||
+ | *separate mask | ||
+ | *fillorder - not needed by baseline tiff reader | ||
+ | *bigtiff 64bit offsets | ||
+ | *XMP tag 700 | ||
+ | *ICC profile tag 34675 | ||
+ | *Orientation with rotation | ||
+ | |||
+ | Working features of the writer: | ||
+ | |||
+ | *Grayscale 8,16bit (optional alpha) | ||
+ | *RGB 8,16bit (optional alpha) | ||
+ | *Orientation except rotated | ||
+ | *multiple images, pages | ||
+ | *thumbnail | ||
+ | *Compression: deflate | ||
+ | |||
+ | Here is an incomplete list of open / not yet implemented features of the writer: | ||
+ | |||
+ | *Compression: LZW, packbits, jpeg, CCIT Group 3,CCIT Group 4,... | ||
+ | *Planar | ||
+ | *ColorMap | ||
+ | *separate mask | ||
+ | *fillorder - not needed by baseline tiff reader | ||
+ | *bigtiff 64bit offsets | ||
+ | *endian - currently using system endianess | ||
+ | *Orientation with rotation | ||
== Walk-through == | == Walk-through == | ||
Line 135: | Line 215: | ||
You'll need a few things to start up. A canvas, image, and writer. The writer is to write images like PNG. The sample below will give you a 100x100 black png. | You'll need a few things to start up. A canvas, image, and writer. The writer is to write images like PNG. The sample below will give you a 100x100 black png. | ||
− | < | + | <syntaxhighlight lang="Pascal">{$mode objfpc}{$h+} |
− | {$mode objfpc}{$h+} | ||
program demo; | program demo; | ||
Line 163: | Line 242: | ||
image.Free; | image.Free; | ||
writer.Free; | writer.Free; | ||
− | end. | + | end.</syntaxhighlight> |
− | </ | ||
=== Drawing a Circle === | === Drawing a Circle === | ||
Line 170: | Line 248: | ||
Drawing a circle requires a bit more then just giving a width. You'll need to setup the pen style, mode, width, and color to do this. FCL-Image comes with a few pen modes and styles, it will really be up to you to decide which you'll need. Its best for now to try with a few modes and styles to get a better understanding of what FCL-Image can do. | Drawing a circle requires a bit more then just giving a width. You'll need to setup the pen style, mode, width, and color to do this. FCL-Image comes with a few pen modes and styles, it will really be up to you to decide which you'll need. Its best for now to try with a few modes and styles to get a better understanding of what FCL-Image can do. | ||
− | + | <syntaxhighlight lang="Pascal">{$mode objfpc}{$h+} | |
− | < | ||
− | {$mode objfpc}{$h+} | ||
program demo; | program demo; | ||
Line 212: | Line 288: | ||
image.Free; | image.Free; | ||
writer.Free; | writer.Free; | ||
− | end. | + | end.</syntaxhighlight> |
− | </ | ||
=== Pen Modes === | === Pen Modes === | ||
Line 247: | Line 322: | ||
* psClear | * psClear | ||
− | == | + | === Drawing text === |
+ | |||
+ | Here is an example, how to create a 200x100 image, painting a white background and some text and saving it as .png: | ||
+ | <syntaxhighlight lang="Pascal">program fontdraw; | ||
+ | |||
+ | {$mode objfpc}{$H+} | ||
+ | |||
+ | uses | ||
+ | Classes, SysUtils, FPimage, FPImgCanv, ftfont, FPWritePNG, FPCanvas; | ||
+ | |||
+ | procedure TestFPImgFont; | ||
+ | var | ||
+ | Img: TFPMemoryImage; | ||
+ | Writer: TFPWriterPNG; | ||
+ | ms: TMemoryStream; | ||
+ | ImgCanvas: TFPImageCanvas; | ||
+ | fs: TFileStream; | ||
+ | AFont: TFreeTypeFont; | ||
+ | begin | ||
+ | Img:=nil; | ||
+ | ImgCanvas:=nil; | ||
+ | Writer:=nil; | ||
+ | ms:=nil; | ||
+ | fs:=nil; | ||
+ | AFont:=nil; | ||
+ | try | ||
+ | // initialize free type font manager | ||
+ | ftfont.InitEngine; | ||
+ | FontMgr.SearchPath:='/usr/share/fonts/truetype/ttf-dejavu/'; | ||
+ | AFont:=TFreeTypeFont.Create; | ||
+ | |||
+ | // create an image of width 200, height 100 | ||
+ | Img:=TFPMemoryImage.Create(200,100); | ||
+ | Img.UsePalette:=false; | ||
+ | // create the canvas with the drawing operations | ||
+ | ImgCanvas:=TFPImageCanvas.create(Img); | ||
+ | |||
+ | // paint white background | ||
+ | ImgCanvas.Brush.FPColor:=colWhite; | ||
+ | ImgCanvas.Brush.Style:=bsSolid; | ||
+ | ImgCanvas.Rectangle(0,0,Img.Width,Img.Height); | ||
+ | |||
+ | // paint text | ||
+ | ImgCanvas.Font:=AFont; | ||
+ | ImgCanvas.Font.Name:='DejaVuSans'; | ||
+ | ImgCanvas.Font.Size:=20; | ||
+ | ImgCanvas.TextOut(10,30,'Test'); | ||
+ | |||
+ | // write image as png to memory stream | ||
+ | Writer:=TFPWriterPNG.create; | ||
+ | ms:=TMemoryStream.Create; | ||
+ | writer.ImageWrite(ms,Img); | ||
+ | // write memory stream to file | ||
+ | ms.Position:=0; | ||
+ | fs:=TFileStream.Create('testfont.png',fmCreate); | ||
+ | fs.CopyFrom(ms,ms.Size); | ||
+ | finally | ||
+ | AFont.Free; | ||
+ | ms.Free; | ||
+ | Writer.Free; | ||
+ | ImgCanvas.Free; | ||
+ | Img.Free; | ||
+ | fs.Free; | ||
+ | end; | ||
+ | end; | ||
+ | |||
+ | begin | ||
+ | TestFPImgFont; | ||
+ | end.</syntaxhighlight> | ||
+ | |||
+ | ===Reading an image file=== | ||
+ | |||
+ | It is very easy to read image files with fcl-image, as the example below shows: | ||
+ | |||
+ | <syntaxhighlight lang="Pascal"> | ||
+ | uses | ||
+ | fpreadgif, fpimage; | ||
+ | |||
+ | var | ||
+ | image: TFPCustomImage; | ||
+ | reader: TFPCustomImageReader; | ||
+ | begin | ||
+ | Image := TFPMemoryImage.Create(10, 10); | ||
+ | Reader := TFPReaderGIF.Create; | ||
+ | Image.LoadFromFile(AFileName, Reader); | ||
+ | // ... | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ===Converting between two raster image formats=== | ||
+ | |||
+ | To convert simply open in one format and save in the desired one, like in this example: | ||
+ | |||
+ | <syntaxhighlight lang="Pascal"> | ||
+ | uses | ||
+ | fpreadgif, fpimage, fpwritebmp; | ||
+ | |||
+ | var | ||
+ | image: TFPCustomImage; | ||
+ | reader: TFPCustomImageReader; | ||
+ | writer: TFPCustomImageWriter; | ||
+ | begin | ||
+ | Image := TFPMemoryImage.Create(10, 10); | ||
+ | Reader := TFPReaderGIF.Create; | ||
+ | Writer := TFPWriterBMP.Create; | ||
+ | |||
+ | Image.LoadFromFile(AFileName, Reader); | ||
+ | Image.SaveToFile(ADestFileName, Writer); | ||
+ | //... | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ===Gamma correction=== | ||
+ | |||
+ | FCL-Image can be used for image transformations, such as '''gamma correction''' (adjustment of pixel values to modify brightness, see https://en.wikipedia.org/wiki/Gamma_correction): | ||
+ | |||
+ | <syntaxhighlight lang="Pascal"> | ||
+ | uses | ||
+ | fpimage, fpreadjpeg, fpwritejpeg, math; | ||
+ | |||
+ | procedure GammaCorrection(const ASrcFile, ADestFile: String; AGamma: Double); | ||
+ | var | ||
+ | img: TFPMemoryImage; | ||
+ | reader: TFPCustomImageReader; | ||
+ | writer: TFPCustomImageWriter; | ||
+ | i, j: Integer; | ||
+ | clr: TFPColor; | ||
+ | begin | ||
+ | Assert(AGamma <> 0.0); | ||
+ | |||
+ | img := TFPMemoryImage.Create(0, 0); | ||
+ | try | ||
+ | reader := TFPReaderJpeg.Create; | ||
+ | try | ||
+ | img.LoadFromFile(ASrcFile, reader); | ||
+ | finally | ||
+ | reader.Free; | ||
+ | end; | ||
+ | |||
+ | for j := 0 to img.Height - 1 do | ||
+ | for i := 0 to img.Width - 1 do | ||
+ | begin | ||
+ | clr := img.Colors[i, j]; | ||
+ | clr.Red := round(((clr.Red / 65535)**AGamma)*65535); | ||
+ | clr.Green := round(((clr.Green / 65535)**AGamma)*65535); | ||
+ | clr.Blue := round(((clr.Blue / 65535)**AGamma)*65535); | ||
+ | img.Colors[i, j] := clr; | ||
+ | end; | ||
+ | |||
+ | writer := TFPWriterJpeg.Create; | ||
+ | try | ||
+ | img.SaveToFile(ADestFile, writer); | ||
+ | finally | ||
+ | writer.Free; | ||
+ | end; | ||
+ | finally | ||
+ | img.Free; | ||
+ | end; | ||
+ | end; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==See also== | ||
+ | |||
+ | * [[Package_List|Packages List]] | ||
+ | * [[Developing with Graphics]] | ||
− | + | [[Category:FCL]] | |
+ | [[Category:Packages]] | ||
+ | [[Category:Graphics]] |
Revision as of 04:49, 22 December 2019
Introduction
FCL-Image started life as "fpimage", pretty much as an attempt to implement a generally portable TImage like class, without the deep win32 and VCL ties.
Current file list
The central units are fpimage and fpcanvas and these are further enhanced by OOP derivation.
- bmpcomn A few structures and constants for the BMP fileformat
- clipping Some utility routines that help with clipping and intersecting of rects.
- ellipses Drawing of ellipses and arcs, and filling ellipses and pies.
- TEllipseInfo
- extinterpolation interpolation filters for TFPCanvas.StretchDraw (
- TBlackmanInterpolation
- TBlackmanSincInterpolation
- TBlackmanBesselInterpolation
- TGaussianInterpolation
- TBoxInterpolation
- THermiteInterpolation
- TLanczosInterpolation
- TQuadraticInterpolation
- TCubicInterpolation
- TCatromInterpolation
- TBilineairInterpolation
- THanningInterpolation
- THammingInterpolation
- fpcanvas Generic Canvas classes.
- TFPCanvasException
- TFPPenException
- TFPBrushException
- TFPFontException
- TFPCustomCanvas
- TFPCanvasHelper
- TFPCustomFont
- TFPCustomFontClass
- TFPCustomPen
- TFPCustomPenClass
- TFPCustomBrush
- TFPCustomBrushClass
- TFPCustomInterpolation
- TFPBaseInterpolation
- TMitchelInterpolation
- TFPCustomCanvas
- TFPCustomDrawFont
- TFPEmptyFont
- TFPCustomDrawPen
- TFPEmptyPen
- TFPCustomDrawBrush
- TFPEmptyBrush
- fpcolhash an implementation of a color hash table.
- TFPColorHashException
- TFPColorHashTable
- fpditherer contains classes used to dither images.
- FPDithererException
- TFPBaseDitherer
- TFPFloydSteinbergDitherer
- fpimage fpImage base definitions and classes
- TFPCustomImageReader
- TFPCustomImageWriter
- TFPCustomImage
- FPImageException
- TFPPalette
- TFPCustomImage
- TFPMemoryImage
- TFPCustomImageHandler
- TFPCustomImageReader
- TFPCustomImageWriter
- TIHData
- TImageHandlersManager
- fpimgcanv Image Canvas - canvas which draws on an image.
- TFPImageCanvas
- fpimgcmn Image Common: small procedural Helpers (swap,crc)
- fppixlcanv
- TPixelCanvas
- fpquantizer classes used to quantize images. See [1]
- freetype Encapsulating classes over freetype
- freetypeh Freetype header translation
- ftfont More freetype related font classes
- pcxcomn PCX fileformat records and types
- pixtools Pixel drawing routines.
- pngcomn PNG fileformat records and types
- pscanvas TPostScriptCanvas implementation.
- targacmn Targa fileformat records and types
Readers and writers for various image formats reside in dedicated units:
- fpreadbmp, fpwritebmp: Reader and writer units for .bmp files
- fpreadjpeg, fpwritejpeg: Reader and writer units for .jpeg/.jpg files
- fpreadpcx, fprwritepcs: Reader and writer units for .pcx files
- fpreadpng, fpwritepng: Reader and writer units for .png files
- fpreadpnm, fpwritepnm: Reader and writer units for .pnm files
- fpreadtga, fpwritetga: Reader and writer units for .tga files
- fpreadtiff, fpwritetiff: Reader and writer units for .tiff/.tif files
- fpreadxpm, fpwritexpm: Reader and writer units for .xpm files
INC files uses in fpcanvas
- fpbrush
- fpcanvas
- fpcdrawh
- fpfont
- fphelper
- fpinterpolation
- fppen
INC files uses in fpmake
- fpcolors
- fpimage
- fphandler
- fpcolcnv
- fppalette
Demos
- drawing
- imgconv
Known Issues and limitations
- fcl-image is written for maximal portability and maintainability and is quite slow. The main storage type is 16-bit RGBA, storing always 64-bit per pixel, and a function is called to get each pixel.
- pngwriter doesn't implement automatic detection of filters, and thus is always "filter none"
- most writers don't autodetect what format to save. You must correctly set the relevant writer options ( see also bug 17621).
- the color format can be counter intuitive, read this thread
- png only implements basic chunk types (idat,trns,plte,ihdr and iend). It e.g. can't handle chunks like pHYs,iCCP,gAMA,cHRM yet. (bug 19209).
Image formats
Here is a table with the correct class to use for each image format, as well as comparing to the LCL.
Format | fcl-image reader unit | fcl-image writer unit | LCL class |
---|---|---|---|
Windows Bitmap. A very simple format, usually used without compression and without transparency, but it may also have them, although many applications don't support those extra features. (*.bmp) | fpreadbmp | fpwritebmp | TBitmap |
A popular format for websites. It supports up to 8 bits per pixels, which are 256 distinct colors chosen from the 24-bit RGB color space. This limitation makes it unsuitable for complex images, but useful for simple graphics. The image is compressed without loss in quality and the format also supports animations. (*.gif) | fpreadgif | - | TGIFImage |
The most popular format for websites, and an ISO standard since 1994. The format compressed the image but generates a small loss of quality. (*.jpeg, *.jpg) | fpreadjpeg | fpwritejpeg | TJpegImage |
A format widely used in DOS applications, but now less popular. (*.pcx) | fpreadpcx | fpwritepcx | - |
Portable Network Graphics. A popular format for it's efficient compression without quality loss. (*.png) | fpreadpng | fpwritepng | TPortableNetworkGraphic |
Supports the formats Portable BitMaps (*.pbm), Portable GrayMaps (*.pgm) and Portable PixMaps (*.ppm) | fpreadpnm | fpwritepnm | TPortableAnyMapGraphic |
The default file format for Adobe Photoshop® (*.psd) | fpreadpsd | - | - |
Called either Truevision TGA File Format or TARGA File Format, this is a compressed format commonly used in games. (*.tga, *.tpic) | fpreadtga | fpwritetga | - |
Tagged Image File Format (TIFF), originally created to have a common image format for scanners. (*.tiff, *.tif). Controlled by Adobe® | fpreadtiff | fpwritetiff | TTiffImage |
X PixMap, an image format used by the X Window System which stores the data in ASCII text. Is also used as an icon format in UNIX applications. (*.xpm) | fpreadxpm | fpwritexpm | TPixmap |
X Window Dump file format. Used by the program xwd which generates screenshots in the X Window System. (*.xwd) | fpreadxwd | - | - |
Windows Icon. Is a list of small bitmaps in various color depths and sizes, with transparency support and no compression. (*.ico) | - | - | TIcon |
Windows Cursor. Exactly the same format as the Windows Icon, but with an extra field in the header for the cursor hotspot. (*.cur) | - | - | TCursorImage |
macOS icon. List of small images in various sizes. (*.icns) | - | - | TIcnsIcon |
Tiff
Working features of the reader:
- Black and white/lineart/1 bit (FPC trunk only, not in FPC 2.6.x)
- Grayscale 8,16bit (optional alpha),
- RGB 8,16bit (optional alpha),
- Orientation, except for rotated orientation
- compression: packbits, LZW, deflate
- endian
- multiple images/multipage
- strips and tiles
- Sets properties in the image Extras properties, which is used by the writer, so that reading/writing keeps many common tags like Artist, Copyright, DateAndTime, HostComputer, ImageDescription, Maker, Model, Software, DocumentName, XResolution, YResolution, Orientation, bit depts, page name, isThumbnail.
Here is an incomplete list of open / not yet implemented features of the reader:
- Compression: jpeg, CCITT Group 3, CCITT Group 4
- PlanarConfiguration 2
- ColorMap
- separate mask
- fillorder - not needed by baseline tiff reader
- bigtiff 64bit offsets
- XMP tag 700
- ICC profile tag 34675
- Orientation with rotation
Working features of the writer:
- Grayscale 8,16bit (optional alpha)
- RGB 8,16bit (optional alpha)
- Orientation except rotated
- multiple images, pages
- thumbnail
- Compression: deflate
Here is an incomplete list of open / not yet implemented features of the writer:
- Compression: LZW, packbits, jpeg, CCIT Group 3,CCIT Group 4,...
- Planar
- ColorMap
- separate mask
- fillorder - not needed by baseline tiff reader
- bigtiff 64bit offsets
- endian - currently using system endianess
- Orientation with rotation
Walk-through
Basic Canvas Setup
You'll need a few things to start up. A canvas, image, and writer. The writer is to write images like PNG. The sample below will give you a 100x100 black png.
{$mode objfpc}{$h+}
program demo;
uses classes, sysutils,
FPImage, FPCanvas, FPImgCanv,
FPWritePNG;
var canvas : TFPCustomCanvas;
image : TFPCustomImage;
writer : TFPCustomImageWriter;
begin
{ Create an image 100x100 pixels}
image := TFPMemoryImage.Create (100,100);
{ Attach the image to the canvas }
Canvas := TFPImageCanvas.Create (image);
{ Create the writer }
Writer := TFPWriterPNG.Create;
{ Save to file }
image.SaveToFile ('DrawTest.png', writer);
{ Clean up! }
Canvas.Free;
image.Free;
writer.Free;
end.
Drawing a Circle
Drawing a circle requires a bit more then just giving a width. You'll need to setup the pen style, mode, width, and color to do this. FCL-Image comes with a few pen modes and styles, it will really be up to you to decide which you'll need. Its best for now to try with a few modes and styles to get a better understanding of what FCL-Image can do.
{$mode objfpc}{$h+}
program demo;
uses classes, sysutils,
FPImage, FPCanvas, FPImgCanv,
FPWritePNG;
var canvas : TFPcustomCanvas;
image : TFPCustomImage;
writer : TFPCustomImageWriter;
{
Colors range from 0 to 65535 in each primary color.
They can also show as hexideciaml:
$FFFF = 65535, $0000 = 0
}
passionRed: TFPColor = (Red: 65535; Green: 0; Blue: 0; Alpha: 65535);
begin
image := TFPMemoryImage.Create (100,100);
Canvas := TFPImageCanvas.Create (image);
Writer := TFPWriterPNG.Create;
{ Set the pen styles }
with canvas do
begin
pen.mode := pmCopy;
pen.style := psSolid;
pen.width := 1;
pen.FPColor := passionRed;
end;
{ Draw a circle }
canvas.Ellipse (10,10, 90,90);
{ Save to file }
image.SaveToFile ('DrawTest.png', writer);
{ Clean up! }
Canvas.Free;
image.Free;
writer.Free;
end.
Pen Modes
The pen mode is how the pixel drawn will react to the pixels beneath it. So if its a white pixel and you draw a red pixel over it with the mode of pmXor then you'll get a vibrate blue pixel.
- pmBlack
- pmWhite
- pmNop
- pmNot
- pmCopy
- pmNotCopy
- pmMergePenNot
- pmMaskPenNot
- pmMergeNotPen
- pmMaskNotPen
- pmMerge
- pmNotMerge
- pmMask
- pmNotMask
- pmXor
- pmNotXor
Pen Styles
- psSolid
- psDash
- psDot
- psDashDot
- psDashDotDot
- psinsideFrame
- psPattern
- psClear
Drawing text
Here is an example, how to create a 200x100 image, painting a white background and some text and saving it as .png:
program fontdraw;
{$mode objfpc}{$H+}
uses
Classes, SysUtils, FPimage, FPImgCanv, ftfont, FPWritePNG, FPCanvas;
procedure TestFPImgFont;
var
Img: TFPMemoryImage;
Writer: TFPWriterPNG;
ms: TMemoryStream;
ImgCanvas: TFPImageCanvas;
fs: TFileStream;
AFont: TFreeTypeFont;
begin
Img:=nil;
ImgCanvas:=nil;
Writer:=nil;
ms:=nil;
fs:=nil;
AFont:=nil;
try
// initialize free type font manager
ftfont.InitEngine;
FontMgr.SearchPath:='/usr/share/fonts/truetype/ttf-dejavu/';
AFont:=TFreeTypeFont.Create;
// create an image of width 200, height 100
Img:=TFPMemoryImage.Create(200,100);
Img.UsePalette:=false;
// create the canvas with the drawing operations
ImgCanvas:=TFPImageCanvas.create(Img);
// paint white background
ImgCanvas.Brush.FPColor:=colWhite;
ImgCanvas.Brush.Style:=bsSolid;
ImgCanvas.Rectangle(0,0,Img.Width,Img.Height);
// paint text
ImgCanvas.Font:=AFont;
ImgCanvas.Font.Name:='DejaVuSans';
ImgCanvas.Font.Size:=20;
ImgCanvas.TextOut(10,30,'Test');
// write image as png to memory stream
Writer:=TFPWriterPNG.create;
ms:=TMemoryStream.Create;
writer.ImageWrite(ms,Img);
// write memory stream to file
ms.Position:=0;
fs:=TFileStream.Create('testfont.png',fmCreate);
fs.CopyFrom(ms,ms.Size);
finally
AFont.Free;
ms.Free;
Writer.Free;
ImgCanvas.Free;
Img.Free;
fs.Free;
end;
end;
begin
TestFPImgFont;
end.
Reading an image file
It is very easy to read image files with fcl-image, as the example below shows:
uses
fpreadgif, fpimage;
var
image: TFPCustomImage;
reader: TFPCustomImageReader;
begin
Image := TFPMemoryImage.Create(10, 10);
Reader := TFPReaderGIF.Create;
Image.LoadFromFile(AFileName, Reader);
// ...
Converting between two raster image formats
To convert simply open in one format and save in the desired one, like in this example:
uses
fpreadgif, fpimage, fpwritebmp;
var
image: TFPCustomImage;
reader: TFPCustomImageReader;
writer: TFPCustomImageWriter;
begin
Image := TFPMemoryImage.Create(10, 10);
Reader := TFPReaderGIF.Create;
Writer := TFPWriterBMP.Create;
Image.LoadFromFile(AFileName, Reader);
Image.SaveToFile(ADestFileName, Writer);
//...
Gamma correction
FCL-Image can be used for image transformations, such as gamma correction (adjustment of pixel values to modify brightness, see https://en.wikipedia.org/wiki/Gamma_correction):
uses
fpimage, fpreadjpeg, fpwritejpeg, math;
procedure GammaCorrection(const ASrcFile, ADestFile: String; AGamma: Double);
var
img: TFPMemoryImage;
reader: TFPCustomImageReader;
writer: TFPCustomImageWriter;
i, j: Integer;
clr: TFPColor;
begin
Assert(AGamma <> 0.0);
img := TFPMemoryImage.Create(0, 0);
try
reader := TFPReaderJpeg.Create;
try
img.LoadFromFile(ASrcFile, reader);
finally
reader.Free;
end;
for j := 0 to img.Height - 1 do
for i := 0 to img.Width - 1 do
begin
clr := img.Colors[i, j];
clr.Red := round(((clr.Red / 65535)**AGamma)*65535);
clr.Green := round(((clr.Green / 65535)**AGamma)*65535);
clr.Blue := round(((clr.Blue / 65535)**AGamma)*65535);
img.Colors[i, j] := clr;
end;
writer := TFPWriterJpeg.Create;
try
img.SaveToFile(ADestFile, writer);
finally
writer.Free;
end;
finally
img.Free;
end;
end;