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

📄 sppngimagelist.pas

📁 一款支持Delphi和C++ Builder的VCL控件
💻 PAS
字号:
{*******************************************************************}
{                                                                   }
{       Almediadev Visual Component Library                         }
{       DynamicSkinForm                                             }
{       Version 9.12                                                }
{                                                                   }
{       Copyright (c) 2000-2007 Almediadev                          }
{       ALL RIGHTS RESERVED                                         }
{                                                                   }
{       Home:  http://www.almdev.com                                }
{       Support: support@almdev.com                                 }
{                                                                   }
{*******************************************************************}

unit spPngImageList;

interface

uses
  Windows, Classes, SysUtils, Controls, Graphics, CommCtrl, ImgList, PngImage;

type
  TspPNGImageList = class;

  TspPngImageItem = class(TCollectionItem)
   private
    FPngImage: TPNGObject;
    FName: string;
    procedure SetPngImage(const Value: TPNGObject);
  protected
    procedure AssignTo(Dest: TPersistent); override;
    function GetDisplayName: string; override;
  public
    constructor Create(Collection: TCollection); override;
    destructor Destroy; override;
    procedure Assign(Source: TPersistent); override;
  published
    property PngImage: TPNGObject read FPngImage write SetPngImage;
    property Name: string read FName write FName;
  end;

  TspPngImageItems = class(TCollection)
  private
    function GetItem(Index: Integer): TspPngImageItem;
    procedure SetItem(Index: Integer; Value:  TspPngImageItem);
  protected
    function GetOwner: TPersistent; override;
  public
    FPngImageList: TspPNGImageList;
    constructor Create(APNGImageList: TspPNGImageList);
    property Items[Index: Integer]:  TspPngImageItem read GetItem write SetItem; default;
  end;

  TspPNGImageList = class(TCustomImageList)
  private
    FPngImages: TspPngImageItems;
    function GetPngWidth: Integer;
    function GetPngHeight: Integer;
    procedure SetPngWidth(Value: Integer);
    procedure SetPngHeight(Value: Integer);
    procedure SetPngImages(Value: TspPngImageItems);
  protected
    procedure DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer; Style: Cardinal; Enabled: Boolean = True); override;
    procedure InsertBitMap(Index: Integer);
    procedure DeleteBitMap(Index: Integer);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property PngImages: TspPngImageItems read FPngImages write SetPngImages;
    property PngWidth: Integer read GetPngWidth write SetPngWidth;
    property PngHeight: Integer read GetPngHeight write SetPngHeight;
  end;

  procedure Register;

implementation


  procedure Register;
  begin
    RegisterComponents('Skin pack', [TspPNGImageList]);
  end;

procedure TspPngImageItem.AssignTo(Dest: TPersistent);
begin
  inherited AssignTo(Dest);
  if (Dest is TspPngImageItem)
  then
    TspPngImageItem(Dest).PngImage := PngImage;
end;

constructor TspPngImageItem.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  FPngImage := TPNGObject.Create;
  FName := Format('PngImage%d', [Index]);
  TspPngImageItems(Self.Collection).FPngImageList.InsertBitmap(Index);
end;

destructor TspPngImageItem.Destroy;
begin
  FPngImage.Free;
  if TspPngImageItems(Self.Collection).FPngImageList.Count > Index
  then
    TspPngImageItems(Self.Collection).FPngImageList.DeleteBitmap(Index);
  inherited Destroy;
end;

procedure TspPngImageItem.Assign(Source: TPersistent);
begin
  if Source is TspPngImageItem
  then
    begin
      PngImage.Assign(TspPngImageItem(Source).PngImage);
      Name := TspPngImageItem(Source).Name;
   end
  else
    inherited Assign(Source);
end;

function TspPngImageItem.GetDisplayName: string;
begin
  if Length(FName) = 0
  then Result := inherited GetDisplayName
  else Result := FName;
end;

procedure TspPngImageItem.SetPngImage(const Value: TPNGObject);
begin
  FPngImage.Assign(Value);
  Changed(False);
end;

constructor TspPngImageItems.Create;
begin
  inherited Create(TspPngImageItem);
  FPngImageList := APngImageList;
end;


function TspPngImageItems.GetOwner: TPersistent;
begin
  Result := FPngImageList;
end;

function TspPngImageItems.GetItem(Index: Integer): TspPngImageItem;
begin
  Result := TspPngImageItem(inherited GetItem(Index));
end;

procedure TspPngImageItems.SetItem;
begin
  inherited SetItem(Index, Value);
end;

constructor TspPNGImageList.Create(AOwner: TComponent);
begin
  inherited;
  FPngImages := TspPngImageItems.Create(Self);
end;

destructor TspPNGImageList.Destroy;
begin
  FPngImages.Free;
  FPngImages := nil;
  inherited;
end;

function TspPNGImageList.GetPngWidth: Integer;
begin
  Result := Width;
end;

function TspPNGImageList.GetPngHeight: Integer;
begin
  Result := Height;
end;

procedure TspPNGImageList.SetPngWidth(Value: Integer);
begin
  if Width <> Value
  then
    begin
      Width := Value;
      if not (csLoading in ComponentState)
      then
        FPngImages.Clear;
    end;
end;

procedure TspPNGImageList.SetPngHeight(Value: Integer);
begin
  if Height <> Value
  then
    begin
      Height := Value;
      if not (csLoading in ComponentState)
      then
      FPngImages.Clear;
    end;
end;


procedure TspPNGImageList.SetPngImages(Value: TspPngImageItems);
begin
  FPngImages.Assign(Value);
end;

procedure TspPNGImageList.DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer; Style: Cardinal; Enabled: Boolean);

procedure MakeImageBlended(Image: TPNGObject; Amount: Byte = 127);

  procedure ForceAlphachannel(BitTransparency: Boolean; TransparentColor: TColor);
  var
     Assigner: TBitmap;
     Temp: TPNGObject;
     X, Y: Integer;
     Line: pngimage.PByteArray;
     Current: TColor;
  begin
  Temp := TPNGObject.Create;
  try
    Assigner := TBitmap.Create;
    try
      Assigner.Width := Image.Width;
      Assigner.Height := Image.Height;
      Temp.Assign(Assigner);
    finally
      Assigner.Free;
     end;
    Temp.CreateAlpha;
    for Y := 0 to Image.Height - 1
    do begin
       Line := Temp.AlphaScanline[Y];
       for X := 0 to Image.Width - 1
       do begin
          Current := Image.Pixels[X, Y];
          Temp.Pixels[X, Y] := Current;
          if BitTransparency and (Current = TransparentColor)
          then Line^[X] := 0
          else Line^[X] := Amount;
          end;
       end;
    Image.Assign(Temp);
  finally
    Temp.Free;
   end;
  end;

var
   X, Y: Integer;
   Line: pngimage.PByteArray;
   Forced: Boolean;
   TransparentColor: TColor;
   BitTransparency: Boolean;
begin
  BitTransparency := Image.TransparencyMode = ptmBit;
  TransparentColor := Image.TransparentColor;
  if not (Image.Header.ColorType in [COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA])
  then
    begin
      Forced := Image.Header.ColorType in [COLOR_GRAYSCALE, COLOR_PALETTE];
      if Forced
      then
        ForceAlphachannel(BitTransparency, TransparentColor)
      else
        Image.CreateAlpha;
    end
  else
   Forced := False;

  if not Forced and (Image.Header.ColorType in [COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA])
  then
     for Y := 0 to Image.Height - 1 do
     begin
       Line := Image.AlphaScanline[Y];
       for X := 0 to Image.Width - 1 do
         if BitTransparency and (Image.Pixels[X, Y] = TransparentColor)
         then
           Line^[X] := 0
         else
           Line^[X] := Round(Line^[X] / 256 * (Amount + 1));
     end;
end;

procedure DrawPNG(Png: TPNGObject; Canvas: TCanvas; const Rect: TRect; AEnabled: Boolean);
var
  PngCopy: TPNGObject;
begin
  if not AEnabled
  then
   begin
     PngCopy := TPNGObject.Create;
     try
       PngCopy.Assign(Png);
       MakeImageBlended(PngCopy);
       PngCopy.Draw(Canvas, Rect);
     finally
       PngCopy.Free;
      end;
    end
  else
    Png.Draw(Canvas, Rect);
end;


var
  PaintRect: TRect;
  Png: TspPngImageItem;
begin
  PaintRect := Rect(X, Y, X + Width, Y + Height);
  Png := TspPngImageItem(FPngImages.Items[Index]);
  if Png <> nil
  then
    DrawPNG(Png.PngImage, Canvas, PaintRect, Enabled);
end;

procedure TspPNGImageList.InsertBitMap(Index: Integer);
var
  B: TBitMap;
begin
  B := TBitMap.Create;
  B.Monochrome := True;
  B.Width := Width;
  B.height := Height;
  Insert(Index, B, nil);
  B.Free;
end;

procedure TspPNGImageList.DeleteBitMap(Index: Integer);
begin
  Delete(Index);
end;

end.

⌨️ 快捷键说明

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