Format PFI

Discussion de programmation pour éviter d'empiéter dans les autres forums

Modérateurs : Modérateurs, Développeurs

Antonio
Administrateur(trice)|Administrateur|Administratrice
Administrateur(trice)|Administrateur|Administratrice
Messages : 12769
Inscription : 28 oct. 2003 22:49

Format PFI

Message 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.
pf
Développeur(se)|Développeur|Développeuse
Développeur(se)|Développeur|Développeuse
Messages : 974
Inscription : 28 avr. 2004 8:45
Version de PhotoFiltre : 6
Système d'exploitation : xp seven
Localisation : 78

Message par pf »

Voyons voyons...... :wink:
Antonio
Administrateur(trice)|Administrateur|Administratrice
Administrateur(trice)|Administrateur|Administratrice
Messages : 12769
Inscription : 28 oct. 2003 22:49

Message 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