📄 freebitmap.pas
字号:
end
else
Result := False
end;
function TFreeBitmap.ConvertToGrayscale: Boolean;
var
ColorType: FREE_IMAGE_COLOR_TYPE;
begin
Result := False;
if FDib <> nil then
begin
ColorType := FreeImage_GetColorType(FDib);
if (ColorType in [FIC_PALETTE, FIC_MINISWHITE]) then
begin
// convert the palette to 24-bit, then to 8-bit
Result := ConvertTo24Bits;
Result := Result and ConvertTo8Bits;
end
else
if FreeImage_GetBPP(FDib) <> 8 then
// convert the bitmap to 8-bit grayscale
Result := ConvertTo8Bits
end
end;
function TFreeBitmap.ConvertToStandartType(ScaleLinear: Boolean): Boolean;
var
dibStandart: PFIBITMAP;
begin
if IsValid then
begin
dibStandart := FreeImage_ConvertToStandardType(FDib, ScaleLinear);
Result := Replace(dibStandart);
end
else
Result := False;
end;
function TFreeBitmap.ConvertToType(ImageType: FREE_IMAGE_TYPE;
ScaleLinear: Boolean): Boolean;
var
dib: PFIBITMAP;
begin
if FDib <> nil then
begin
dib := FreeImage_ConvertToType(FDib, ImageType, ScaleLinear);
Result := Replace(dib)
end
else
Result := False
end;
function TFreeBitmap.CopySubImage(Left, Top, Right, Bottom: Integer;
Dest: TFreeBitmap): Boolean;
begin
if FDib <> nil then
begin
Dest.FDib := FreeImage_Copy(FDib, Left, Top, Right, Bottom);
Result := Dest.IsValid;
end else
Result := False;
end;
constructor TFreeBitmap.Create(ImageType: FREE_IMAGE_TYPE; Width, Height,
Bpp: Integer);
begin
FDib := nil;
if (Width > 0) and (Height > 0) and (Bpp > 0) then
SetSize(ImageType, Width, Height, Bpp);
end;
destructor TFreeBitmap.Destroy;
begin
if FDib <> nil then
FreeImage_Unload(FDib);
inherited;
end;
function TFreeBitmap.Dither(Algorithm: FREE_IMAGE_DITHER): Boolean;
var
dib: PFIBITMAP;
begin
if FDib <> nil then
begin
dib := FreeImage_Dither(FDib, Algorithm);
Result := Replace(dib);
end
else
Result := False;
end;
function TFreeBitmap.FlipHorizontal: Boolean;
begin
if FDib <> nil then
begin
Result := FreeImage_FlipHorizontal(FDib);
Change;
end
else
Result := False
end;
function TFreeBitmap.FlipVertical: Boolean;
begin
if FDib <> nil then
begin
Result := FreeImage_FlipVertical(FDib);
Change;
end
else
Result := False
end;
function TFreeBitmap.GetBitsPerPixel: Integer;
begin
Result := FreeImage_GetBPP(FDib)
end;
function TFreeBitmap.GetChannel(Bitmap: TFreeBitmap;
Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
begin
if FDib <> nil then
begin
Bitmap.FDib := FreeImage_GetChannel(FDib, Channel);
Result := Bitmap.IsValid;
end
else
Result := False
end;
function TFreeBitmap.GetColorsUsed: Integer;
begin
Result := FreeImage_GetColorsUsed(FDib)
end;
function TFreeBitmap.GetColorType: FREE_IMAGE_COLOR_TYPE;
begin
Result := FreeImage_GetColorType(FDib)
end;
function TFreeBitmap.GetFileBkColor(var BkColor: PRGBQuad): Boolean;
begin
Result := FreeImage_GetBackgroundColor(FDib, BkColor)
end;
function TFreeBitmap.GetHeight: Integer;
begin
Result := FreeImage_GetHeight(FDib)
end;
function TFreeBitmap.GetHistogram(Histo: PDWORD;
Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean;
begin
if FDib <> nil then
Result := FreeImage_GetHistogram(FDib, Histo, Channel)
else
Result := False
end;
function TFreeBitmap.GetHorizontalResolution: Integer;
begin
Result := FreeImage_GetDotsPerMeterX(FDib) div 100
end;
function TFreeBitmap.GetImageSize: Cardinal;
begin
Result := FreeImage_GetDIBSize(FDib);
end;
function TFreeBitmap.GetImageType: FREE_IMAGE_TYPE;
begin
Result := FreeImage_GetImageType(FDib)
end;
function TFreeBitmap.GetInfo: PBitmapInfo;
begin
Result := FreeImage_GetInfo(FDib^)
end;
function TFreeBitmap.GetInfoHeader: PBITMAPINFOHEADER;
begin
Result := FreeImage_GetInfoHeader(FDib)
end;
function TFreeBitmap.GetLine: Integer;
begin
Result := FreeImage_GetLine(FDib)
end;
function TFreeBitmap.GetPalette: PRGBQUAD;
begin
Result := FreeImage_GetPalette(FDib)
end;
function TFreeBitmap.GetPaletteSize: Integer;
begin
Result := FreeImage_GetColorsUsed(FDib) * SizeOf(RGBQUAD)
end;
function TFreeBitmap.GetPixelColor(X, Y: Cardinal;
var Value: PRGBQUAD): Boolean;
begin
Result := FreeImage_GetPixelColor(FDib, X, Y, Value)
end;
function TFreeBitmap.GetPixelIndex(X, Y: Cardinal;
var Value: PByte): Boolean;
begin
Result := FreeImage_GetPixelIndex(FDib, X, Y, Value)
end;
function TFreeBitmap.GetScanLine(ScanLine: Integer): PByte;
var
H: Integer;
begin
H := FreeImage_GetHeight(FDib);
if ScanLine < H then
Result := FreeImage_GetScanLine(FDib, ScanLine)
else
Result := nil;
end;
function TFreeBitmap.GetScanWidth: Integer;
begin
Result := FreeImage_GetPitch(FDib)
end;
function TFreeBitmap.GetTransparencyCount: Cardinal;
begin
Result := FreeImage_GetTransparencyCount(FDib)
end;
function TFreeBitmap.GetTransparencyTable: PByte;
begin
Result := FreeImage_GetTransparencyTable(FDib)
end;
function TFreeBitmap.GetVerticalResolution: Integer;
begin
Result := FreeImage_GetDotsPerMeterY(Fdib) div 100
end;
function TFreeBitmap.GetWidth: Integer;
begin
Result := FreeImage_GetWidth(FDib)
end;
function TFreeBitmap.HasFileBkColor: Boolean;
begin
Result := FreeImage_HasBackgroundColor(FDib)
end;
function TFreeBitmap.Invert: Boolean;
begin
if FDib <> nil then
begin
Result := FreeImage_Invert(FDib);
Change;
end
else
Result := False
end;
function TFreeBitmap.IsGrayScale: Boolean;
begin
Result := (FreeImage_GetBPP(FDib) = 8)
and (FreeImage_GetColorType(FDib) = FIC_PALETTE);
end;
function TFreeBitmap.IsTransparent: Boolean;
begin
Result := FreeImage_IsTransparent(FDib);
end;
function TFreeBitmap.IsValid: Boolean;
begin
Result := FDib <> nil
end;
function TFreeBitmap.Load(const FileName: string; Flag: Integer): Boolean;
var
fif: FREE_IMAGE_FORMAT;
begin
// check the file signature and get its format
fif := FreeImage_GetFileType(PChar(Filename), 0);
if fif = FIF_UNKNOWN then
// no signature?
// try to guess the file format from the file extention
fif := FreeImage_GetFIFFromFilename(PChar(FileName));
// check that the plugin has reading capabilities ...
if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(FIF) then
begin
// free the previous dib
if FDib <> nil then
FreeImage_Unload(dib);
// load the file
FDib := FreeImage_Load(fif, PChar(FileName), Flag);
Change;
Result := IsValid;
end else
Result := False;
end;
function TFreeBitmap.LoadFromHandle(IO: PFreeImageIO; Handle: fi_handle;
Flag: Integer): Boolean;
var
fif: FREE_IMAGE_FORMAT;
begin
// check the file signature and get its format
fif := FreeImage_GetFileTypeFromHandle(IO, Handle, 16);
if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(fif) then
begin
// free the previous dib
if FDib <> nil then
FreeImage_Unload(FDib);
// load the file
FDib := FreeImage_LoadFromHandle(fif, IO, Handle, Flag);
Change;
Result := IsValid;
end else
Result := False;
end;
function TFreeBitmap.LoadFromMemory(MemIO: TFreeMemoryIO;
Flag: Integer): Boolean;
var
fif: FREE_IMAGE_FORMAT;
begin
// check the file signature and get its format
fif := MemIO.GetFileType;
if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(fif) then
begin
// free the previous dib
if FDib <> nil then
FreeImage_Unload(FDib);
// load the file
FDib := MemIO.Read(fif, Flag);
Result := IsValid;
Change;
end else
Result := False;
end;
const
ThumbSize = 150;
procedure TFreeBitmap.MakeThumbnail(const Width, Height: Integer;
DestBitmap: TFreeBitmap);
type
PRGB24 = ^TRGB24;
TRGB24 = packed record
B: Byte;
G: Byte;
R: Byte;
end;
var
x, y, ix, iy: integer;
x1, x2, x3: integer;
xscale, yscale: single;
iRed, iGrn, iBlu, iRatio: Longword;
p, c1, c2, c3, c4, c5: TRGB24;
pt, pt1: PRGB24;
iSrc, iDst, s1: integer;
i, j, r, g, b, tmpY: integer;
RowDest, RowSource, RowSourceStart: integer;
w, h: Integer;
dxmin, dymin: integer;
ny1, ny2, ny3: integer;
dx, dy: integer;
lutX, lutY: array of integer;
SrcBmp, DestBmp: PFIBITMAP;
begin
if not IsValid then Exit;
if (GetWidth <= ThumbSize) and (GetHeight <= ThumbSize) then
begin
DestBitmap.Assign(Self);
Exit;
end;
w := Width;
h := Height;
// prepare bitmaps
if GetBitsPerPixel <> 24 then
SrcBmp := FreeImage_ConvertTo24Bits(FDib)
else
SrcBmp := FDib;
DestBmp := FreeImage_Allocate(w, h, 24);
Assert(DestBmp <> nil, 'TFreeBitmap.MakeThumbnail error');
{ iDst := (w * 24 + 31) and not 31;
iDst := iDst div 8; //BytesPerScanline
iSrc := (GetWidth * 24 + 31) and not 31;
iSrc := iSrc div 8;
}
// BytesPerScanline
iDst := FreeImage_GetPitch(DestBmp);
iSrc := FreeImage_GetPitch(SrcBmp);
xscale := 1 / (w / FreeImage_GetWidth(SrcBmp));
yscale := 1 / (h / FreeImage_GetHeight(SrcBmp));
// X lookup table
SetLength(lutX, w);
x1 := 0;
x2 := trunc(xscale);
for x := 0 to w - 1 do
begin
lutX[x] := x2 - x1;
x1 := x2;
x2 := trunc((x + 2) * xscale);
end;
// Y lookup table
SetLength(lutY, h);
x1 := 0;
x2 := trunc(yscale);
for x := 0 to h - 1 do
begin
lutY[x] := x2 - x1;
x1 := x2;
x2 := trunc((x + 2) * yscale);
end;
Dec(w);
Dec(h);
RowDest := integer(FreeImage_GetScanLine(DestBmp, 0));
RowSourceStart := integer(FreeImage_GetScanLine(SrcBmp, 0));
RowSource := RowSourceStart;
for y := 0 to h do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -