📄 be_bitmap.pas
字号:
begin
{ palette contains too many entries, shorten it }
for I := 0 to MaxOut do
begin
LogPalette.palPalEntry[I].peRed := LogPalette.palPalEntry[MulDiv16(I, MaxIn, MaxOut)].peRed;
LogPalette.palPalEntry[I].peGreen := LogPalette.palPalEntry[MulDiv16(I, MaxIn, MaxOut)].peGreen;
LogPalette.palPalEntry[I].peBlue := LogPalette.palPalEntry[MulDiv16(I, MaxIn, MaxOut)].peBlue;
end;
end;
LogPalette.palNumEntries := MaxOut + 1;
end;
{ finally create palette }
Result := CreatePalette(PLogPalette(@LogPalette)^);
end;
procedure MakePalette;
var
PCXPalette: array[0..255] of TRGB;
OldPos: Integer;
Marker: Byte;
begin
if (Header.Version <> 3) or (Bitmap.PixelFormat = pf1Bit) and
(Bitmap.PixelFormat = pf8Bit) then
begin
OldPos := Stream.Position;
{ 256 colors with 3 components plus one marker byte }
Stream.Position := Stream.Size - 769;
Stream.Read(Marker, 1);
Stream.Read(PCXPalette[0], 768);
Bitmap.Palette := PcxCreateColorPalette([@PCXPalette], 256);
Stream.Position := OldPos;
end
else
Bitmap.Palette := SystemPalette16;
end;
procedure RowConvertIndexed8(Source: array of Pointer; Target: Pointer; Count: Cardinal; Mask: Byte);
var
SourceRun, TargetRun: PByte;
begin
SourceRun := Source[0];
TargetRun := Target;
if (FSourceBPS = FTargetBPS) and (Mask = $FF) then
Move(SourceRun^, TargetRun^, (Count * FSourceBPS + 7) div 8);
end;
var
PCXSize, Size: Cardinal;
RawBuffer, DecodeBuffer: Pointer;
Run: PByte;
I: Integer;
Line: PByte;
Increment: Cardinal;
begin
{ Load from PCX - 8-bit indexed RLE compressed/uncompressed }
{$WARNINGS OFF}
Bitmap := TBitmap.Create;
try
Bitmap.Handle := 0;
Stream.Read(Header, SizeOf(Header));
PCXSize := Stream.Size - Stream.Position;
with Header do
begin
if not (FileID in [$0A, $CD]) then Exit;
Bitmap.PixelFormat := pf8bit;
MakePalette;
Bitmap.Width := XMax - XMin + 1;
Bitmap.Height := YMax - YMin + 1;
{ adjust alignment of line }
Increment := ColorPlanes * BytesPerLine;
{ Decompress }
if Header.Encoding = 1 then
begin
{ RLE }
Size := Increment * Bitmap.Height;
GetMem(DecodeBuffer, Size);
GetMem(RawBuffer, PCXSize);
try
Stream.ReadBuffer(RawBuffer^, PCXSize);
PcxDecode(RawBuffer, DecodeBuffer, PCXSize, Size);
finally
if Assigned(RawBuffer) then FreeMem(RawBuffer);
end;
end
else
begin
GetMem(DecodeBuffer, PCXSize);
Stream.ReadBuffer(DecodeBuffer^, PCXSize);
end;
try
Run := DecodeBuffer;
{ PCX 8 bit Index }
for I := 0 to Bitmap.Height - 1 do
begin
Line := Bitmap.ScanLine[I];
RowConvertIndexed8([Run], Line, Bitmap.Width, $FF);
Inc(Run, Increment);
end;
finally
if Assigned(DecodeBuffer) then FreeMem(DecodeBuffer);
end;
end;
{ Assign to Self }
Assign(Bitmap);
finally
Bitmap.Free;
end;
{$WARNINGS ON}
end;
{ Checking routines }
const
Quantity = 6;
procedure TbeBitmap.CheckingAlphaBlend;
var
i: Cardinal;
C: PbeColor;
begin
FAlphaBlend := false;
C := @FBits[0];
for i := 0 to FWidth * FHeight - 1 do
begin
if (TbeColorRec(C^).A > 0) and (TbeColorRec(C^).A < $FF) then
begin
FAlphaBlend := true;
Break;
end;
Inc(C);
end;
end;
procedure TbeBitmap.CheckingAlphaBlend(ARect: TRect);
var
i, j: integer;
C: PbeColor;
begin
FAlphaBlend := false;
for i := 0 to FWidth - 1 do
for j := 0 to FHeight - 1 do
begin
C := PixelPtr[i, j];
if (TbeColorRec(C^).A > 0) and (TbeColorRec(C^).A < $FF) then
begin
FAlphaBlend := true;
Break;
end;
end;
end;
procedure TbeBitmap.CheckingTransparent(Color: TbeColor = beTransparent);
var
i: Cardinal;
C: PbeColor;
begin
FTransparent := false;
C := @FBits[0];
for i := 0 to FWidth * FHeight - 1 do
begin
if (Abs(TbeColorRec(C^).R - TbeColorRec(Color).R) < Quantity) and
(Abs(TbeColorRec(C^).G - TbeColorRec(Color).G) < Quantity) and
(Abs(TbeColorRec(C^).B - TbeColorRec(Color).B) < Quantity)
then
begin
C^ := beTransparent;
FTransparent := true;
end;
Inc(C);
end;
end;
procedure TbeBitmap.CheckingTransparent(ARect: TRect; Color: TbeColor = beTransparent);
var
i, j: integer;
C: PbeColor;
begin
FTransparent := false;
for i := 0 to FWidth - 1 do
for j := 0 to FHeight - 1 do
begin
C := PixelPtr[i, j];
if (Abs(TbeColorRec(C^).R - TbeColorRec(Color).R) < Quantity) and
(Abs(TbeColorRec(C^).G - TbeColorRec(Color).G) < Quantity) and
(Abs(TbeColorRec(C^).B - TbeColorRec(Color).B) < Quantity)
then
begin
C^ := beTransparent;
FTransparent := true;
end;
end;
end;
procedure TbeBitmap.SetAlpha(Alpha: byte);
begin
if Empty then Exit;
FillAlphaFunc(Bits, FWidth * FHeight, Alpha);
end;
procedure TbeBitmap.SetAlpha(Alpha: byte; Rect: TRect);
begin
if RectWidth(Rect) = 0 then Exit;
if RectHeight(Rect) = 0 then Exit;
if Rect.Left < 0 then Rect.Left := 0;
if Rect.Top < 0 then Rect.Top := 0;
if Rect.Right > FWidth then Rect.Right := FWidth;
if Rect.Bottom > FHeight then Rect.Bottom := FHeight;
FillAlphaRectFunc(FBits, FWidth, FHeight, Rect.Left, Rect.Top, Rect.Right-1,
Rect.Bottom - 1, Alpha);
end;
{ Access properties }
function TbeBitmap.GetScanLine(Y: Integer): PbeColorArray;
begin
Result := @Bits[Y * FWidth];
end;
function TbeBitmap.GetPixelPtr(X, Y: Integer): PbeColor;
begin
Result := @Bits[X + Y * FWidth];
end;
function TbeBitmap.GetPixel(X, Y: Integer): TbeColor;
begin
if (FBits <> nil) and (X >= 0) and (Y >= 0) and (X < Width) and (Y < Height) then
Result := PixelPtr[X, Y]^
else
Result := 0;
end;
procedure TbeBitmap.SetPixel(X, Y: Integer; Value: TbeColor);
begin
if X < 0 then Exit;
if Y < 0 then Exit;
if X > Width then Exit;
if Y > Height then Exit;
if FBits <> nil then
PixelPtr[X, Y]^ := Value;
end;
{ BitmapLink }
function TbeBitmap.GetBitmapLink(Rect: TRect): TbeBitmapLink;
begin
Result := TbeBitmapLink.Create;
Result.Image := Self;
Result.Name := Name;
Result.Rect := Rect;
end;
function TbeBitmap.GetBitmapLink(Rect: string): TbeBitmapLink;
begin
Result := TbeBitmapLink.Create;
Result.Image := Self;
Result.Name := Name;
Result.Rect := StringToRect(Rect);
end;
{ Color transition ============================================================}
procedure TbeBitmap.ChangeBitmapBrightness(DeltaBrightness: integer);
var
i: Cardinal;
Color: PbeColor;
A: byte;
begin
if DeltaBrightness = 0 then Exit;
if FWidth * FHeight = 0 then Exit;
for i := 0 to FWidth * FHeight - 1 do
begin
Color := @Bits[i];
A := TbeColorRec(Color^).A;
if (A = 0) then Continue;
Color^ := ChangeBrightness(Color^, DeltaBrightness);
Color^ := Color^ and not AlphaMask or (A shl 24);
end;
end;
procedure TbeBitmap.SetBitmapHue(Hue: integer);
var
i: Cardinal;
Color: PbeColor;
A: byte;
begin
if FWidth * FHeight = 0 then Exit;
for i := 0 to FWidth * FHeight - 1 do
begin
Color := @Bits[i];
A := TbeColorRec(Color^).A;
if (A = 0) then Continue;
Color^ := SetHue(Color^, Hue);
Color^ := Color^ and not AlphaMask or (A shl 24);
end;
end;
procedure TbeBitmap.ChangeBitmapSat(DeltaSat: integer);
var
i: Cardinal;
Color: PbeColor;
A: byte;
begin
if DeltaSat = 0 then Exit;
if FWidth * FHeight = 0 then Exit;
for i := 0 to FWidth * FHeight - 1 do
begin
Color := @Bits[i];
A := TbeColorRec(Color^).A;
if (A = 0) then Continue;
Color^ := ChangeSat(Color^, DeltaSat);
Color^ := Color^ and not AlphaMask or (A shl 24);
end;
end;
procedure TbeBitmap.ChangeBitmapHue(DeltaHue: integer);
var
i: Cardinal;
Color: PbeColor;
A: byte;
begin
if DeltaHue = 0 then Exit;
if FWidth * FHeight = 0 then Exit;
for i := 0 to FWidth * FHeight - 1 do
begin
Color := @Bits[i];
A := TbeColorRec(Color^).A;
if (A = 0) then Continue;
Color^ := ChangeHue(Color^, DeltaHue);
Color^ := Color^ and not AlphaMask or (A shl 24);
end;
end;
{ Draw to XXX =================================================================}
procedure TbeBitmap.Draw(DC: HDC; X, Y: integer);
begin
Draw(DC, X, Y, Rect(0, 0, Width, Height));
end;
procedure TbeBitmap.Draw(DC: HDC; X, Y: integer; SrcRect: TRect);
begin
Draw(DC, Rect(X, Y, X + RectWidth(SrcRect), Y + RectHeight(SrcRect)), SrcRect);
end;
procedure TbeBitmap.Draw(DC: HDC; DstRect: TRect);
begin
Draw(DC, DstRect, Rect(0, 0, FWidth, FHeight));
end;
procedure TbeBitmap.Draw(DC: HDC; DstRect, SrcRect: TRect);
{$WARNINGS OFF}
var
Dst: TbeBitmap;
P: TPoint;
BitmapW, BitmapH, BitmapBCount: integer;
BitmapBits: PByteArray;
begin
Dst := FindBitmapByDC(DC);
if Dst <> nil then
begin
{ Adjust WindowOrg }
GetWindowOrgEx(DC, P);
OffsetRect(DstRect, -P.X, -P.Y);
{ Destination is KS Bitmap }
Draw(Dst, DstRect, SrcRect);
end
else
begin
(* BitmapBits := GetBitsFromDCFunc(DC, BitmapW, BitmapH, BitmapBCount);
if EnableDibOperation and (BitmapBits <> nil) and (BitmapBCount = 32) and (BitmapH > 0) then
begin
{ Adjust WindowOrg }
GetWindowOrgEx(DC, P);
OffsetRect(DstRect, -P.X, -P.Y);
{ Draw to DIB }
if FAlphaBlend then
StretchToDibAlphaBlendFunc(BitmapBits, DstRect, DstRect, BitmapW, BitmapH,
Self, SrcRect)
else
if FTransparent then
StretchToDibTransparentFunc(BitmapBits, DstRect, DstRect, BitmapW, BitmapH,
Self, SrcRect)
else
StretchToDibOpaqueFunc(BitmapBits, DstRect, DstRect, BitmapW, BitmapH,
Self, SrcRect);
end
else *)
begin
{ Draw to DC }
if FAlphaBlend then
StretchToDCAlphaBlendFunc(DC, DstRect.Left, DstRect.Top, RectWidth(DstRect), RectHeight(DstRect),
Self, SrcRect.Left, SrcRect.Top, RectWidth(SrcRect), RectHeight(SrcRect))
else
if FTransparent then
StretchToDCTransparentFunc(DC, DstRect.Left, DstRect.Top, RectWidth(DstRect), RectHeight(DstRect),
Self, SrcRect.Left, SrcRect.Top, RectWidth(SrcRect), RectHeight(SrcRect))
else
StretchToDCOpaqueFunc(DC, DstRect.Left, DstRect.Top, RectWidth(DstRect), RectHeight(DstRect),
Self, SrcRect.Left, SrcRect.Top, RectWidth(SrcRect), RectHeight(SrcRect));
end;
end;
{$WARNINGS ON}
end;
procedure TbeBitmap.Draw(Canvas: TCanvas; X, Y: integer);
begin
{$IFNDEF KS_CLX}
Draw(Canvas.Handle, X, Y);
{$ELSE}
Canvas.Start;
try
QPainter_drawImage(Canvas.Handle, X, Y, FImage, 0, 0, FWidth, FHeight, -1);
finally
Canvas.Stop;
end;
{$ENDIF}
end;
procedure TbeBitmap.Draw(Canvas: TCanvas; X, Y: integer; SrcRect: TRect);
begin
Draw(Canvas, Rect(X, Y, X + RectWidth(SrcRect), Y + RectHeight(SrcRect)), SrcRect);
end;
procedure TbeBitmap.Draw(Canvas: TCanvas; DstRect: TRect);
begin
Draw(Canvas, DstRect, Rect(0, 0, FWidth, FHeight));
end;
procedure TbeBitmap.Draw(Canvas: TCanvas; DstRect, SrcRect: TRect);
begin
{$IFNDEF KS_CLX}
Draw(Canvas.Handle, DstRect, SrcRect);
{$ELSE}
Canvas.Start;
try
QPainter_drawImage(Canvas.Handle, X, Y, FImage, 0, 0, FWidth, FHeight, -1);
finally
Canvas.Stop;
end;
{$ENDIF}
end;
procedure TbeBitmap.Draw(Bitmap: TbeBitmap; X, Y: integer);
begin
Draw(Bitmap, X, Y, Rect(0, 0, Width, Height));
end;
procedure TbeBitmap.Draw(Bitmap: TbeBitmap; X, Y: integer;
SrcRect: TRect);
begin
Draw(Bitmap, Rect(X, Y, X + RectWidth(SrcRect), Y + RectHeight(SrcRect)), SrcRect);
end;
procedure TbeBitmap.Draw(Bitmap: TbeBitmap; DstRect: TRect);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -