⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fcbitmap.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
unit fcBitmap;
{
//
// Components : TfcBitmap
//
// Copyright (c) 1999 by Woll2Woll Software
// 12/3/99 - Only use DibColor table if it is valid.
//           Previously just checked if colors[0] was 0 for valid determination
// 12/4/99 - Support true color bitmaps in 256 color environments by creating
//           half-tone palette
// 12/7/99 - new method Changecolor used by fcImgBtn
// 11/1/2001 - Use Draw when loading from graphic as this is more generic and allows Graphic to define how it is drawn to the bitmap.
}
interface

{$i fcIfDef.pas}

uses Windows, Graphics, Classes, fcGraphics, fcChangeLink, SysUtils;

type
  TfcColor = record
    b, g, r: Byte
  end;
  PfcColor = ^TfcColor;

  TfcLine = array[0..0] of TfcColor;
  PfcLine = ^TfcLine;

  TfcPLines = array[0..0] of PfcLine;
  PfcPLines = ^TfcPLines;

  TfcBitmap = class(TGraphic)
  private
    FSmoothStretching: Boolean;
    FTransparentColor: TColor;

    FWidth: Integer;
    FHeight: Integer;
    FGap: Integer;
    FMaskBitmap: TBitmap;
    FRowInc: Integer;
    FSize: Integer;
    FBits: Pointer;
    FHandle: Integer;
    FDC: HDC;
    FCanvas: TCanvas;

    FMemoryImage: Pointer;
    FMemorySize: Integer;
    FMemoryDim: TSize;

    FPixelFormat: TPixelFormat;
    FPalette: HPALETTE;
    FRespectPalette: Boolean;
    FUseHalftonePalette: boolean;

    FIgnoreChange: Boolean;
    FChangeLinks: TList;

//    FPicture: TPicture;

    bmInfo: TBitmapInfo;
    bmHeader: TBitmapInfoHeader;
    function GetSleeping: Boolean;
    procedure InitHeader;
  protected
    Assigning: Boolean;
    SkipPalette: boolean;

    Procedure RestoreBitmapPalette(ACanvas: TCanvas; OldPalette: HPalette); virtual;
    Procedure SelectBitmapPalette(ACanvas: TCanvas; var OldPalette: HPalette); virtual;
    function GetEmpty: Boolean; override;
    function GetHeight: Integer; override;
    function GetWidth: Integer; override;
    procedure AssignTo(Dest: TPersistent); override;
    procedure Changed(Sender: TObject); override;
    procedure Draw(ACanvas: TCanvas; const Rect: TRect); override;
    procedure SetHeight(Value: Integer); override;
    procedure SetWidth(Value: Integer); override;

    procedure CleanUp; virtual;
    procedure Initialize; virtual;
    procedure NotifyChanges; virtual;
    procedure PaletteNeeded; virtual;

    property Gap: Integer read FGap;
    property RowInc: Integer read FRowInc;
    property DC: HDC read FDC;
  public
    Patch: Variant;
    Pixels: PfcPLines;
    Colors: array[Byte] of TRGBQuad;

    constructor Create; override;
    destructor Destroy; override;

    procedure Assign(Source: TPersistent); override;

    procedure RegisterChanges(ChangeLink: TfcChangeLink); virtual;
    procedure UnRegisterChanges(ChangeLink: TfcChangeLink); virtual;

    procedure Clear; virtual;
    procedure FreeMemoryImage; virtual;
    procedure LoadBlank(AWidth, AHeight: Integer); virtual;
    procedure LoadFromBitmap(Bitmap: TBitmap); virtual;
    procedure LoadFromJPEG(JPEG: TGraphic); virtual;
    procedure LoadFromClipboardFormat(AFormat: Word; AData: THandle;
      APalette: HPALETTE); override;
    procedure LoadFromGraphic(Graphic: TGraphic); virtual;
    procedure LoadFromMemory(ABits: Pointer; ASize: Integer; Dimensions: TSize); virtual;
    procedure LoadFromStream(Stream: TStream); override;
    procedure SaveToBitmap(Bitmap: TBitmap); virtual;
    procedure SaveToClipboardFormat(var AFormat: Word; var AData: THandle;
      var APalette: HPALETTE); override;
    procedure SaveToStream(Stream: TStream); override;
    procedure SetSize(const AWidth, AHeight: Integer); virtual;

    function GetMaskBitmap: TBitmap;
    function CopyPixels: PfcPLines;
    procedure Fill(Color: TColor);
    procedure Resize(AWidth, AHeight: Integer); virtual;
    procedure Sleep; virtual;
    procedure SmoothStretchDraw(ACanvas: TCanvas; Rect: TRect); virtual;
    procedure StretchDraw(ACanvas: TCanvas; const Rect: TRect); virtual;
    procedure TileDraw(ACanvas: TCanvas; ARect: TRect); virtual;
    procedure TransparentDraw(ACanvas: TCanvas; const Rect: TRect); virtual;
    procedure Wake; virtual;

    // Filters
    procedure AlphaBlend(Bitmap: TfcBitmap; Alpha: Integer; Stretch: Boolean);
    procedure Blur(Amount: Integer); virtual;
    procedure Contrast(Amount: Integer); virtual;
    procedure Emboss; virtual;
    procedure Flip(Horizontal: Boolean); virtual;
    procedure GaussianBlur(Amount: Integer); virtual;
    procedure Grayscale; virtual;
    procedure Invert; virtual;
    procedure Brightness(Amount: Integer); virtual;
    procedure Mask(MaskColor: TfcColor); virtual;

    { 12/7/99 - new method Changecolor used by fcImgBtn }
    procedure ChangeColor(OldColor: TfcColor; NewColor: TfcColor); virtual;
    procedure ColorTint(ra, ga, ba: Integer); virtual;
    procedure Colorize(ra, ga, ba: Integer); virtual;
    procedure Rotate(Center: TPoint; Angle: Extended); virtual;
    procedure Saturation(Amount: Integer); virtual;
    procedure Sharpen(Amount: Integer); virtual;
    procedure Sponge(Amount: Integer); virtual;
    procedure Wave(XDiv, YDiv, RatioVal: Extended; Wrap: Boolean); virtual;

    property Bits: Pointer read FBits;
    property Canvas: TCanvas read FCanvas;
    property Handle: Integer read FHandle;
    property IgnoreChange: Boolean read FIgnoreChange write FIgnoreChange;
    property MaskBitmap: TBitmap read GetMaskBitmap;
    property RespectPalette: Boolean read FRespectPalette write FRespectPalette;
    property UseHalftonePalette: Boolean read FUseHalftonePalette write FUseHalftonePalette;
    property SmoothStretching: Boolean read FSmoothStretching write FSmoothStretching;
    property Sleeping: Boolean read GetSleeping;
    property Size: Integer read FSize;
    property TransparentColor: TColor read FTransparentColor write FTransparentColor;
  end;

function fcGetColor(Color: TColor): TfcColor;
function fcGetStdColor(Color: TfcColor): TColor;
function fcRGB(r, g, b: Byte): TfcColor;
function fcIntToByte(Value: Integer): Byte;
function fcTrimInt(i, Min, Max: Integer): Integer;

implementation

uses
{$ifdef fcdelphi6Up}
variants,
{$endif}
 fcCommon;
{$R-}

function fcGetColor(Color: TColor): TfcColor;
begin
  //2/17/99 - Get Actual Color Value
  Color := ColorToRGB(Color);
  result.r := Color and $FF;
  result.g := Color and $FF00 shr 8;
  result.b := Color and $FF0000 shr 16;
end;

function fcGetStdColor(Color: TfcColor): TColor;
begin
  with Color do result := RGB(r, g, b);
end;

function fcRGB(r, g, b: Byte): TfcColor;
begin
  result.r := r;
  result.g := g;
  result.b := b;
end;

function fcIntToByte(Value: Integer): Byte;
begin
  if Value > 255 then result := 255
  else if Value < 0 then result := 0
  else result := Value;
end;

function fcTrimInt(i, Min, Max: Integer): Integer;
begin
  if i > Max then result := Max
  else if i < Min then result := Min
  else result := i;
end;

constructor TfcBitmap.Create;
begin
  inherited;
  FCanvas := TCanvas.Create;
  FChangeLinks := TList.Create;
  FTransparentColor := clNone;
  FPixelFormat := pf24Bit;
  Patch:= VarArrayCreate([0, 1], varVariant);
  Patch[0]:= False;     { Color table not valid }
  Patch[1]:= False;
end;

destructor TfcBitmap.Destroy;
begin
  FChangeLinks.Free;
  if Sleeping then FreeMemoryImage;
  CleanUp;
  FCanvas.Free;
  inherited;
end;

function TfcBitmap.GetSleeping: Boolean;
begin
  result := (FMemorySize > 0) and (FMemoryImage <> nil);
end;

function TfcBitmap.GetEmpty: Boolean;
begin
  result := FHandle = 0;
end;

function TfcBitmap.GetHeight: Integer;
begin
  result := FHeight;
end;

function TfcBitmap.GetWidth: Integer;
begin
  result := FWidth;
end;

procedure TfcBitmap.Assign(Source: TPersistent);
begin
  if (Source is TBitmap) and not (Source as TBitmap).Empty then
  begin
    FPixelFormat := (Source as TBitmap).PixelFormat;
    LoadFromBitmap(Source as TBitmap);
    Transparent := (Source as TBitmap).Transparent;
//    TransparentColor := (Source as TBitmap).TransparentColor;
  end else if (Source = nil) or ((Source is TBitmap) and (Source as TBitmap).Empty) then
  begin
    CleanUp;
    Changed(self);
  end else if (Source is TGraphic) and not (Source is TfcBitmap) then
  begin
    LoadFromGraphic(Source as TGraphic);
  end else inherited;
end;

procedure TfcBitmap.AssignTo(Dest: TPersistent);
begin
  if Dest is TBitmap then
  begin
    (Dest as TBitmap).PixelFormat := self.FPixelFormat;
    SaveToBitmap(Dest as TBitmap);
    (Dest as TBitmap).Transparent := Transparent;
    (Dest as TBitmap).TransparentColor := TransparentColor;
  end else if Dest is TfcBitmap then
    with TfcBitmap(Dest) do
  begin
    if not self.Empty then
    begin
      IgnoreChange := True;
      RespectPalette := self.RespectPalette;
      UseHalftonePalette:= self.UseHalftonePalette;
      LoadBlank(self.Width, self.Height);
      CopyMemory(TfcBitmap(Dest).Bits, self.Bits, self.Size);
      Transparent := self.Transparent;
      SmoothStretching := self.SmoothStretching;
      TransparentColor := self.TransparentColor;
      FPixelFormat := self.FPixelFormat;
      CopyMemory(@(Dest as TfcBitmap).Colors, @self.Colors, SizeOf(self.Colors));
      Patch[0]:= self.Patch[0];
      Patch[1]:= self.Patch[1]; // Halftone value
//      FHalfTone:= self.FHalfTone;

      IgnoreChange := False;
      Changed(Dest);
    end else begin
      CleanUp;
      Changed(Dest);
    end;
  end else inherited;
end;

procedure TfcBitmap.Changed(Sender: TObject);
begin
  if not IgnoreChange then
  begin
    inherited Changed(Sender);
    NotifyChanges;
  end;
end;

procedure TfcBitmap.NotifyChanges;
var i: Integer;
begin
  for i := 0 to FChangeLinks.Count - 1 do with TfcChangeLink(FChangeLinks[i]) do
  begin
    Sender := self;
    Change;
  end;
end;

procedure TfcBitmap.RegisterChanges(ChangeLink: TfcChangeLink);
begin
  FChangeLinks.Add(ChangeLink);
end;

procedure TfcBitmap.UnRegisterChanges(ChangeLink: TfcChangeLink);
begin
  FChangeLinks.Remove(ChangeLink);
end;

procedure TfcBitmap.TransparentDraw(ACanvas: TCanvas; const Rect: TRect);
var Bmp: TBitmap;
begin
  Bmp := TBitmap.Create;
  Bmp.Width := Width;
  Bmp.Height := Height;
  Bmp.PixelFormat := pf24Bit;
  Bmp.Canvas.CopyRect(Classes.Rect(0, 0, Width, Height), Canvas, Classes.Rect(0, 0, Width, Height));
  fcDrawMask(ACanvas, Rect, Bmp, MaskBitmap, True);
  Bmp.Free;
end;

procedure TfcBitmap.StretchDraw(ACanvas: TCanvas; const Rect: TRect);
var TempBitmap: TfcBitmap;
begin
  if Transparent then
  begin
    TempBitmap := TfcBitmap.Create;
    TempBitmap.LoadBlank(fcRectWidth(Rect), fcRectHeight(Rect));
    StretchBlt(TempBitmap.Canvas.Handle, 0, 0, TempBitmap.Width, TempBitmap.Height,
      FDC, 0, 0, FWidth, FHeight, SRCCOPY);
    TempBitmap.TransparentDraw(ACanvas, Rect);
    TempBitmap.Free;
  end else begin
    SetStretchBltMode(ACanvas.Handle, COLORONCOLOR);
    with Rect do StretchBlt(ACanvas.Handle, Left, Top, Right - Left, Bottom - Top,
      FDC, 0, 0, FWidth, FHeight, SRCCOPY);
  end;
end;

Procedure TfcBitmap.RestoreBitmapPalette(ACanvas: TCanvas; OldPalette: HPalette);
begin
  if (GetDeviceCaps(FDC, BITSPIXEL) <= 8)
     and (RespectPalette or UseHalftonePalette) then
  begin
    SelectPalette(ACanvas.Handle, OldPalette, True);
    if FPalette <> 0 then
    begin
      DeleteObject(FPalette);
      FPalette := 0;
    end;
  end;
end;

Procedure TfcBitmap.SelectBitmapPalette(ACanvas: TCanvas; var OldPalette: HPalette);
var
    DC: HDC;
begin
  if (GetDeviceCaps(FDC, BITSPIXEL) <= 8) then begin
     if RespectPalette or UseHalftonePalette then
     begin
       if RespectPalette then
       begin
          PaletteNeeded;
       end
       else if UseHalftonePalette then begin
          DC := GetDC(0);
          FPalette := CreateHalftonePalette(DC);
          ReleaseDC(0, DC);
       end;
       OldPalette := SelectPalette(ACanvas.Handle, FPalette, True);
       RealizePalette(ACanvas.Handle);
    end
  end
end;

procedure TfcBitmap.Draw(ACanvas: TCanvas; const Rect: TRect);
  function Transparent: Boolean;
  begin
    result := self.Transparent and not Assigning;
  end;
  function SmoothStretching: Boolean;
  begin
    result := self.SmoothStretching and not Assigning;
  end;
var OldPalette: HPALETTE;
//    DC: HDC;
begin
  OldPalette := 0;
  if not SkipPalette then SelectBitmapPalette(ACanvas, OldPalette);
{  if (GetDeviceCaps(FDC, BITSPIXEL) <= 8) and (not SkipPalette) then begin
     if RespectPalette or UseHalftonePalette then
     begin
       if RespectPalette then
       begin
          PaletteNeeded;
       end
       else if UseHalftonePalette then begin
          DC := GetDC(0);
          FPalette := CreateHalftonePalette(DC);
          ReleaseDC(0, DC);
       end;
       OldPalette := SelectPalette(ACanvas.Handle, FPalette, True);
       RealizePalette(ACanvas.Handle);
     end
  end;}

  with Rect do
  begin
    if ((Right - Left) = Width) and ((Bottom - Top) = Height) then
    begin
      if Transparent then TransparentDraw(ACanvas, Rect)
      else BitBlt(ACanvas.Handle, Left, Top, Right - Left, Bottom - Top, FDC, 0, 0, SRCCOPY);
    end else begin
      if FSmoothStretching then SmoothStretchDraw(ACanvas, Rect)
      else StretchDraw(ACanvas, Rect);
    end;
  end;
  if not SkipPalette then RestoreBitmapPalette(ACanvas, OldPalette);
{
  if (GetDeviceCaps(FDC, BITSPIXEL) <= 8) and (not SkipPalette)
     and (RespectPalette or UseHalftonePalette) then
  begin
    SelectPalette(ACanvas.Handle, OldPalette, True);
    if FPalette <> 0 then
    begin
      DeleteObject(FPalette);
      FPalette := 0;
    end;
  end;
}
end;

procedure TfcBitmap.Initialize;
var x, i: Integer;
    TempDC: HDC;
begin
  GetMem(Pixels, FHeight * SizeOf(PfcLine));
  FRowInc := (FWidth * 3) + FWidth mod 4;
  FGap := FWidth mod 4;
  FSize := FRowInc * FHeight;
  x := Integer(Bits);
  for i := 0 to Height - 1 do
  begin
    Pixels[i] := Pointer(x);
    Inc(x, RowInc);
  end;
  TempDC := GetDC(0);
  FDC := CreateCompatibleDC(TempDC);
  ReleaseDC(0, TempDC);
  SelectObject(FDC, FHandle);
  if Handle = 0 then CleanUp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -