Page 1 sur 1

Format PFI

Publié : 11 nov. 2005 11:27
par Antonio
Les sources ci-dessous permettent de lire les propriétés, la miniature et le calque de fond dans un fichier PFI (Image PhotoFiltre Studio). Pour le moment, j'utilise un format RGB qui est plus rapide et plus simple. La couche Alpha sera gérée dans la prochaine version.

Code : Tout sélectionner

// Format PFI - PhotoFiltre Studio
// Antonio DA CRUZ - Novembre 2005
// Dernière modification : 10/11/2005

unit PFImage;

interface

uses
  Windows, Classes, Graphics;

type
  TPFProperties = record
    Version: Integer;
    Width: Integer;
    Height: Integer;
    DPI: Double;
    Comment: string;
    ColorCount: Integer; 
  end;

  TPFImage = class(TBitmap)
  private
    FProperties: TPFProperties;
  public
    procedure LoadFromStream(Stream: TStream); override;
    procedure LoadPropertiesFromStream(Stream: TStream);
    procedure LoadPropertiesFromFile(const FileName: string);
    procedure LoadThumbFromStream(Stream: TStream);
    procedure LoadThumbFromFile(const FileName: string);
    property Properties: TPFProperties read FProperties;
  end;

function IsPfiFile(const FileName: string): Boolean;

implementation

uses
  SysUtils;

// Pour le moment, une seule extension -----------------------------------------

function IsPfiFile(const FileName: string): Boolean;
begin
  Result := LowerCase(ExtractFileExt(FileName)) = '.pfi';
end;

// Permet de charger les données RGB brutes ------------------------------------
// (compression non gérée pour le moment)

procedure LoadRGBFromStream(Bmp: TBitmap; Stream: TStream);
var
  I, LineSize: Integer;
begin
  Bmp.Assign(nil);
  Bmp.PixelFormat := pf24bit;
  // dimensions
  Stream.ReadBuffer(I, SizeOf(I));
  Bmp.Width := I;
  Stream.ReadBuffer(I, SizeOf(I));
  Bmp.Height := I;
  // lignes
  LineSize := Bmp.Width * 3;
  for I := 0 to Bmp.Height - 1 do
    Stream.ReadBuffer(Bmp.ScanLine[I]^, LineSize);
end;

// Charge les propriétés -------------------------------------------------------

procedure TPFImage.LoadPropertiesFromStream(Stream: TStream);
var
  I: Integer;
  Buffer: array[0..255] of Char;
begin
  // signature
  Stream.ReadBuffer(Buffer, 17);
  if StrLComp(Buffer, 'PhotoFiltre Image', 17) <> 0 then
    raise EStreamError.Create('');
  // version
  Stream.ReadBuffer(Buffer, 1);
  FProperties.Version := Ord(Buffer[0]);
  // dimensions du fond
  Stream.ReadBuffer(I, SizeOf(I));
  FProperties.Width := I;
  Stream.ReadBuffer(I, SizeOf(I));
  FProperties.Height := I;
  // résolution
  Stream.ReadBuffer(I, SizeOf(I));
  FProperties.DPI := I / 1000;
  // reservé
  Stream.ReadBuffer(I, SizeOf(I));
  // commentaire (256 caractères)
  Stream.ReadBuffer(Buffer, 256);
  FProperties.Comment := Buffer;
  // ColorCount
  Stream.ReadBuffer(I, SizeOf(I));
  FProperties.ColorCount := I;
end;

procedure TPFImage.LoadPropertiesFromFile(const FileName: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    LoadPropertiesFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

// Charge la miniature ---------------------------------------------------------

procedure TPFImage.LoadThumbFromStream(Stream: TStream);
var
  I: Integer;
  Buffer: array[0..8] of Char;
begin
  LoadPropertiesFromStream(Stream);
  // taille en octets de la zone miniature
  Stream.ReadBuffer(I, SizeOf(I));
  // signature
  Stream.ReadBuffer(Buffer, 9);
  if StrLComp(Buffer, 'Thumbnail', 9) <> 0 then
    raise EStreamError.Create('');
  // réservé
  Stream.ReadBuffer(I, SizeOf(I));
  // données RGB de la miniature
  LoadRGBFromStream(Self, Stream);
end;

procedure TPFImage.LoadThumbFromFile(const FileName: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    LoadThumbFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

// Charge le fond (premier calque ) --------------------------------------------

procedure TPFImage.LoadFromStream(Stream: TStream);
var
  I: Integer;
  Buffer: array[0..255] of Char;
begin
  LoadPropertiesFromStream(Stream);
  // taille en octets de la zone miniature
  Stream.ReadBuffer(I, SizeOf(I));
  // saute la zone miniature
  Stream.Seek(I - SizeOf(I), soFromCurrent);
  // nombre de calques
  Stream.ReadBuffer(I, SizeOf(I));
  // propriétés du calque (non détaillées ici)
  Stream.ReadBuffer(I, SizeOf(I));
  Stream.ReadBuffer(Buffer, I);
  Stream.Seek(38, soFromCurrent);
  // données RGB du fond
  LoadRGBFromStream(Self, Stream);
  // transparence
  Stream.ReadBuffer(Buffer, 1);
  Transparent := Buffer[0] <> #0;
  Stream.ReadBuffer(I, SizeOf(I));
  TransparentColor := TColor(I);
end;

end.

Publié : 11 nov. 2005 12:00
par pf
Voyons voyons...... :wink:

Publié : 11 nov. 2005 14:23
par Antonio
Et oui pas de dll pour le moment, mais l'onconvénient c'est qu'on peut charger uniquement la calque de fond