unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Graphics, Dialogs, StdCtrls, ExtCtrls, LCLType,
ExtDlgs;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
lblPixelFormat: TLabel;
lblInfo: TLabel;
OpenPictureDialog1: TOpenPictureDialog;
Shape1: TShape;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer
);
private
LoadedPixelFormat: TPixelFormat;
procedure GetRGBA(X, Y: Integer; out R, G, B, A: Byte);
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
uses
TypInfo, FPImage, Controls;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
// Point 1: Make sure TImage 'maps' correctly to the loaded picture coordinates.
Image1.Align := alCustom;
Image1.Anchors := [akTop, akLeft];
Image1.Constraints.MaxHeight := Image1.Height;
Image1.Constraints.MaxWidth := Image1.Width;
Image1.AutoSize := True;
// Point 4: Additonal information
Image1.ShowHint := true;
lblPixelFormat.ShowHint := true;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
FileExt: string;
begin
// Point 2: using OpenPictureDialog
if not(OpenPictureDialog1.Execute) then Exit;
Image1.Enabled := True;
lblPixelFormat.Visible := True;
lblInfo.Visible := True;
// Open the file
// Point 3: let TImage do all the hard work for us.
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
// Inspect the pixelformat
LoadedPixelFormat := (Image1.Picture.Graphic as TRasterImage).PixelFormat;
// Show Pixel Format info
case LoadedPixelFormat of
pfDevice: lblPixelFormat.Caption := 'Pixel Format'+#13+'Device';
pf1bit: lblPixelFormat.Caption := 'Pixel Format'+#13+'1-bit';
pf4bit: lblPixelFormat.Caption := 'Pixel Format'+#13+'4-bit';
pf8bit: lblPixelFormat.Caption := 'Pixel Format'+#13+'8-bit';
pf15bit: lblPixelFormat.Caption := 'Pixel Format'+#13+'15-bit';
pf16bit: lblPixelFormat.Caption := 'Pixel Format'+#13+'16-bit';
pf24bit: lblPixelFormat.Caption := 'Pixel Format'+#13+'24-bit';
pf32bit: lblPixelFormat.Caption := 'Pixel Format'+#13+'32-bit';
pfCustom: lblPixelFormat.Caption := 'Pixel Format'+#13+'Custom';
end;
// Clear previous info
Shape1.Brush.Color := clBackground;
lblInfo.Caption := '';
// Point 4: some extra information for TImage and Loaded picture
Image1.Hint:= Format
(
'TImage information : ' + sLineBreak + sLineBreak +
'Left,Top' + ': %d,%d' + sLineBreak +
'Width,Height' + ': %d,%d' + sLineBreak +
'AutoSize' + ': %s' + sLineBreak +
'Center' + ': %s' + sLineBreak +
'Proportional' + ': %s' + sLineBreak +
'Stretch' + ': %s' + sLineBreak +
'Transparent' + ': %s'
,
[
Image1.Left, Image1.Top,
Image1.Width, Image1.Height,
BoolToStr(Image1.AutoSize , 'On', 'Off'),
BoolToStr(Image1.Center , 'On', 'Off'),
BoolToStr(Image1.Proportional, 'On', 'Off'),
BoolToStr(Image1.Stretch , 'On', 'Off'),
BoolToStr(Image1.Transparent , 'On', 'Off')
]
);
lblPixelFormat.Hint := Format
(
'TPicture information:' + sLineBreak + sLineBreak +
'ClassName' + ': %s' + sLineBreak +
'MimeType' + ': %s' + sLineBreak +
'PixelFormat' + ': %s' + sLineBreak +
'TransparentMode' + ': %s' + sLineBreak +
'Transparent' + ': %s' + sLineBreak +
'TransparentColor' + ': $%X' + sLineBreak +
'Masked' + ': %s'
,
[
Image1.Picture.Graphic.ClassName,
Image1.Picture.Graphic.MimeType,
GetEnumName(TypeInfo(TPixelFormat), Ord((Image1.Picture.Graphic as TRasterImage).PixelFormat)),
GetEnumName(TypeInfo(TTransparentMode), Ord((Image1.Picture.Graphic as TRasterImage).TransparentMode)),
BoolToStr(Image1.Picture.Graphic.Transparent, 'Yes', 'No'),
(Image1.Picture.Graphic as TRasterImage).TransparentColor,
BoolToStr((Image1.Picture.Graphic as TRasterImage).Masked, 'Yes', 'No')
]
);
end;
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
Alpha: string;
ValR, ValG, ValB, ValA : Byte;
begin
GetRGBA(X, Y, ValR, ValG, valB, ValA);
// These are the only pixelformats i'm familiar with that _could_
// contain alpha. Other pixelformats are indexed (using a palette) or are
// (afaik) not applicable (e.g. pfDevice/pfCustom).
// Seeing how LCL handles things, only 32-bit pictures _can_ use active
// alpha.
// (note how LCL loads all non bmp data as either 24 or 32 bit, at least on
// Windows platform).
if LoadedPixelFormat in [pf15bit, pf16bit, pf32bit] then
begin
case LoadedPixelFormat of
pf15bit : Alpha := 'A = <unknown15> - Send us the picture';
pf16bit : Alpha := 'A = <unknown16> - Send us the picture';
pf32bit : WriteStr(Alpha, 'A = ', ValA);
end;
end
else Alpha := '';
Shape1.Brush.Color := RGBToColor(ValR, ValG, ValB);
lblInfo.Caption :=
'X = '+IntToStr(X)+ #13+
'Y = '+IntToStr(Y)+ #13+
'R = '+IntToStr(ValR)+ #13+
'G = '+IntToStr(ValG)+ #13+
'B = '+IntToStr(ValB)+ #13+
Alpha;
end;
procedure TForm1.GetRGBA(X, Y: Integer; out R, G, B, A: Byte);
var
ScanData: Pointer;
Data32bit: PRGBQuad absolute ScanData;
col: TFPColor;
begin
// Why does returned TPFcolor not contain Alpha value !?
Col := (Image1.Picture.Graphic as TRasterImage).Canvas.Colors[X, Y];
R := Col.red div 256;
G := Col.green div 256;
B := Col.blue div 256;
with (Image1.Picture.Graphic as TRasterImage) do
begin
ScanData := ScanLine[Y];
case LoadedPixelFormat of
pf15bit :
begin
A := 15;
end;
pf16bit :
begin
A := 16;
end;
pf32bit :
begin
Inc(ScanData, X * 4);
A := Data32bit^.rgbReserved;
end;
else
begin
A := 0;
end;
end;
end;
end;
end.