|
@@ -17,6 +17,7 @@ type
|
|
BGRAPreview: TBGRAVirtualScreen;
|
|
BGRAPreview: TBGRAVirtualScreen;
|
|
Button_Cancel: TButton;
|
|
Button_Cancel: TButton;
|
|
Button_OK: TButton;
|
|
Button_OK: TButton;
|
|
|
|
+ CheckBox_Lossless: TCheckBox;
|
|
CheckBox_Dithering: TCheckBox;
|
|
CheckBox_Dithering: TCheckBox;
|
|
Edit_QualityValue: TEdit;
|
|
Edit_QualityValue: TEdit;
|
|
Label1: TLabel;
|
|
Label1: TLabel;
|
|
@@ -42,6 +43,7 @@ type
|
|
procedure BGRAPreviewRedraw(Sender: TObject; Bitmap: TBGRABitmap);
|
|
procedure BGRAPreviewRedraw(Sender: TObject; Bitmap: TBGRABitmap);
|
|
procedure Button_OKClick(Sender: TObject);
|
|
procedure Button_OKClick(Sender: TObject);
|
|
procedure CheckBox_DitheringChange(Sender: TObject);
|
|
procedure CheckBox_DitheringChange(Sender: TObject);
|
|
|
|
+ procedure CheckBox_LosslessChange(Sender: TObject);
|
|
procedure Edit_QualityValueChange(Sender: TObject);
|
|
procedure Edit_QualityValueChange(Sender: TObject);
|
|
procedure Edit_QualityValueExit(Sender: TObject);
|
|
procedure Edit_QualityValueExit(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
@@ -55,24 +57,30 @@ type
|
|
FInit: boolean;
|
|
FInit: boolean;
|
|
FLazPaintInstance: TLazPaintCustomInstance;
|
|
FLazPaintInstance: TLazPaintCustomInstance;
|
|
FOutputFilename: string;
|
|
FOutputFilename: string;
|
|
- FQualityVisible, FBitsPerPixelVisible: boolean;
|
|
|
|
- FFlattenedOriginal, FJpegPreview: TBGRABitmap;
|
|
|
|
- FBmpStream, FJpegStream, FPngStream: TMemoryStream;
|
|
|
|
|
|
+ FQualityVisible, FLosslessVisible, FBitsPerPixelVisible: boolean;
|
|
|
|
+ FFlattenedOriginal, FJpegPreview, FWebPPreview: TBGRABitmap;
|
|
|
|
+ FBmpStream, FJpegStream, FWebPStream, FPngStream: TMemoryStream;
|
|
FFormTitle: string;
|
|
FFormTitle: string;
|
|
FImageFormat: TBGRAImageFormat;
|
|
FImageFormat: TBGRAImageFormat;
|
|
FQuantizer, FQuantizer1bit: TBGRAColorQuantizer;
|
|
FQuantizer, FQuantizer1bit: TBGRAColorQuantizer;
|
|
FSizeCaption: string;
|
|
FSizeCaption: string;
|
|
function GetBmpStreamNeeded: boolean;
|
|
function GetBmpStreamNeeded: boolean;
|
|
procedure BmpQualityChanged;
|
|
procedure BmpQualityChanged;
|
|
|
|
+ function GetLosslessVisible: boolean;
|
|
function GetPngStreamNeeded: boolean;
|
|
function GetPngStreamNeeded: boolean;
|
|
|
|
+ function GetWebPLossless: boolean;
|
|
procedure PngQualityChanged;
|
|
procedure PngQualityChanged;
|
|
function GetBitsPerPixelVisible: boolean;
|
|
function GetBitsPerPixelVisible: boolean;
|
|
function GetColorQuantizer: TBGRAColorQuantizer;
|
|
function GetColorQuantizer: TBGRAColorQuantizer;
|
|
function GetJpegPreview: TBGRABitmap;
|
|
function GetJpegPreview: TBGRABitmap;
|
|
procedure RequireJpegStream;
|
|
procedure RequireJpegStream;
|
|
|
|
+ function GetWebPPreview: TBGRABitmap;
|
|
|
|
+ procedure RequireWebPStream;
|
|
procedure MakeBmpStreamIfNeeded;
|
|
procedure MakeBmpStreamIfNeeded;
|
|
function GetWantedBitsPerPixel: integer;
|
|
function GetWantedBitsPerPixel: integer;
|
|
procedure SetJpegQuality(AValue: integer);
|
|
procedure SetJpegQuality(AValue: integer);
|
|
|
|
+ procedure SetLosslessVisible(AValue: boolean);
|
|
|
|
+ procedure SetWebPLossless(AValue: boolean);
|
|
procedure UpdateFileSize;
|
|
procedure UpdateFileSize;
|
|
procedure UpdateFileSizeTo(AValue: int64);
|
|
procedure UpdateFileSizeTo(AValue: int64);
|
|
function GetJpegQuality: integer;
|
|
function GetJpegQuality: integer;
|
|
@@ -90,11 +98,13 @@ type
|
|
function GetOriginalBitDepth: integer;
|
|
function GetOriginalBitDepth: integer;
|
|
procedure DoUpdateBitmap;
|
|
procedure DoUpdateBitmap;
|
|
procedure JpegQualityChanged;
|
|
procedure JpegQualityChanged;
|
|
|
|
+ procedure WebPQualityChanged;
|
|
procedure LayoutRadioButtonDepth;
|
|
procedure LayoutRadioButtonDepth;
|
|
procedure MakePngStreamIfNeeded;
|
|
procedure MakePngStreamIfNeeded;
|
|
public
|
|
public
|
|
{ public declarations }
|
|
{ public declarations }
|
|
property QualityVisible: boolean read GetQualityVisible write SetQualityVisible;
|
|
property QualityVisible: boolean read GetQualityVisible write SetQualityVisible;
|
|
|
|
+ property LosslessVisible: boolean read GetLosslessVisible write SetLosslessVisible;
|
|
property BitsPerPixelVisible: boolean read GetBitsPerPixelVisible write SetBitsPerPixelVisible;
|
|
property BitsPerPixelVisible: boolean read GetBitsPerPixelVisible write SetBitsPerPixelVisible;
|
|
property LazPaintInstance: TLazPaintCustomInstance read FLazPaintInstance write SetLazPaintInstance;
|
|
property LazPaintInstance: TLazPaintCustomInstance read FLazPaintInstance write SetLazPaintInstance;
|
|
property OutputFilename: string read FOutputFilename write SetOutputFilename;
|
|
property OutputFilename: string read FOutputFilename write SetOutputFilename;
|
|
@@ -103,6 +113,8 @@ type
|
|
property QuantizerNeeded: boolean read GetQuantizerNeeded;
|
|
property QuantizerNeeded: boolean read GetQuantizerNeeded;
|
|
property JpegPreview: TBGRABitmap read GetJpegPreview;
|
|
property JpegPreview: TBGRABitmap read GetJpegPreview;
|
|
property JpegQuality: integer read GetJpegQuality write SetJpegQuality;
|
|
property JpegQuality: integer read GetJpegQuality write SetJpegQuality;
|
|
|
|
+ property WebPPreview: TBGRABitmap read GetWebPPreview;
|
|
|
|
+ property WebPLossless: boolean read GetWebPLossless write SetWebPLossless;
|
|
property WantedBitsPerPixel: integer read GetWantedBitsPerPixel;
|
|
property WantedBitsPerPixel: integer read GetWantedBitsPerPixel;
|
|
property BmpStreamNeeded: boolean read GetBmpStreamNeeded;
|
|
property BmpStreamNeeded: boolean read GetBmpStreamNeeded;
|
|
property PngStreamNeeded: boolean read GetPngStreamNeeded;
|
|
property PngStreamNeeded: boolean read GetPngStreamNeeded;
|
|
@@ -114,13 +126,13 @@ implementation
|
|
|
|
|
|
uses UGraph, FPWriteJPEG, UResourceStrings, FPWriteBMP, BMPcomn,
|
|
uses UGraph, FPWriteJPEG, UResourceStrings, FPWriteBMP, BMPcomn,
|
|
UMySLV, BGRAWriteBmpMioMap, BGRADithering, UFileSystem, LCScaleDPI,
|
|
UMySLV, BGRAWriteBmpMioMap, BGRADithering, UFileSystem, LCScaleDPI,
|
|
- BGRAThumbnail, BGRAIconCursor, BGRAWinResource;
|
|
|
|
|
|
+ BGRAThumbnail, BGRAIconCursor, BGRAWinResource, BGRAWriteWebP;
|
|
|
|
|
|
function ShowSaveOptionDialog(AInstance: TLazPaintCustomInstance; AOutputFilenameUTF8: string; ASkipOptions: boolean): boolean;
|
|
function ShowSaveOptionDialog(AInstance: TLazPaintCustomInstance; AOutputFilenameUTF8: string; ASkipOptions: boolean): boolean;
|
|
var f: TFSaveOption;
|
|
var f: TFSaveOption;
|
|
begin
|
|
begin
|
|
result := false;
|
|
result := false;
|
|
- if not ASkipOptions and (SuggestImageFormat(AOutputFilenameUTF8) in[ifBmp,ifJpeg,ifPng,ifIco,ifCur]) then
|
|
|
|
|
|
+ if not ASkipOptions and (SuggestImageFormat(AOutputFilenameUTF8) in[ifBmp,ifJpeg,ifWebP,ifPng,ifIco,ifCur]) then
|
|
begin
|
|
begin
|
|
f := TFSaveOption.Create(nil);
|
|
f := TFSaveOption.Create(nil);
|
|
try
|
|
try
|
|
@@ -153,6 +165,7 @@ begin
|
|
UpdateQualityTextBox;
|
|
UpdateQualityTextBox;
|
|
FFormTitle:= Caption;
|
|
FFormTitle:= Caption;
|
|
FQualityVisible:= false;
|
|
FQualityVisible:= false;
|
|
|
|
+ FLosslessVisible:= true;
|
|
FBitsPerPixelVisible:= false;
|
|
FBitsPerPixelVisible:= false;
|
|
Panel_Quality.Visible := FQualityVisible;
|
|
Panel_Quality.Visible := FQualityVisible;
|
|
Panel_BitsPerPixel.Visible := FBitsPerPixelVisible;
|
|
Panel_BitsPerPixel.Visible := FBitsPerPixelVisible;
|
|
@@ -166,8 +179,10 @@ begin
|
|
FreeAndNil(FQuantizer);
|
|
FreeAndNil(FQuantizer);
|
|
FreeAndNil(FQuantizer1bit);
|
|
FreeAndNil(FQuantizer1bit);
|
|
FreeAndNil(FJpegPreview);
|
|
FreeAndNil(FJpegPreview);
|
|
|
|
+ FreeAndNil(FWebPPreview);
|
|
FreeAndNil(FBmpStream);
|
|
FreeAndNil(FBmpStream);
|
|
FreeAndNil(FJpegStream);
|
|
FreeAndNil(FJpegStream);
|
|
|
|
+ FreeAndNil(FWebPStream);
|
|
FreeAndNil(FPngStream);
|
|
FreeAndNil(FPngStream);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -271,7 +286,12 @@ begin
|
|
if ImageFormat = ifJpeg then
|
|
if ImageFormat = ifJpeg then
|
|
begin
|
|
begin
|
|
mustFreePic:= false;
|
|
mustFreePic:= false;
|
|
- picture := GetJpegPreview;
|
|
|
|
|
|
+ picture := JpegPreview;
|
|
|
|
+ end else
|
|
|
|
+ if (ImageFormat = ifWebP) and not WebPLossless then
|
|
|
|
+ begin
|
|
|
|
+ mustFreePic:= false;
|
|
|
|
+ picture := WebPPreview;
|
|
end else
|
|
end else
|
|
if BmpStreamNeeded and (FBmpStream = nil) then
|
|
if BmpStreamNeeded and (FBmpStream = nil) then
|
|
begin
|
|
begin
|
|
@@ -293,6 +313,7 @@ begin
|
|
picture := FFlattenedOriginal;
|
|
picture := FFlattenedOriginal;
|
|
end;
|
|
end;
|
|
MakePngStreamIfNeeded;
|
|
MakePngStreamIfNeeded;
|
|
|
|
+ if ImageFormat = ifWebP then RequireWebPStream;
|
|
|
|
|
|
if (Bitmap.Width = 0) or (Bitmap.Height = 0) or (picture.Width = 0) or (picture.Height = 0) then exit;
|
|
if (Bitmap.Width = 0) or (Bitmap.Height = 0) or (picture.Width = 0) or (picture.Height = 0) then exit;
|
|
ratioX := Bitmap.Width/picture.Width;
|
|
ratioX := Bitmap.Width/picture.Width;
|
|
@@ -447,6 +468,22 @@ procedure TFSaveOption.Button_OKClick(Sender: TObject);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ procedure SaveWebP;
|
|
|
|
+ var outputStream: TStream;
|
|
|
|
+ begin
|
|
|
|
+ RequireWebPStream;
|
|
|
|
+ outputStream := FileManager.CreateFileStream(FOutputFilename,fmCreate);
|
|
|
|
+ try
|
|
|
|
+ FWebPStream.Position := 0;
|
|
|
|
+ outputStream.CopyFrom(FWebPStream, FWebPStream.Size);
|
|
|
|
+ FLazPaintInstance.Config.SetDefaultJpegQuality(JpegQuality);
|
|
|
|
+ FLazPaintInstance.Config.SetDefaultWebPLossless(WebPLossless);
|
|
|
|
+ if FLazPaintInstance.Image.NbLayers = 1 then FLazPaintInstance.Image.SetSavedFlag;
|
|
|
|
+ finally
|
|
|
|
+ outputStream.Free;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
begin
|
|
begin
|
|
try
|
|
try
|
|
Case ImageFormat of
|
|
Case ImageFormat of
|
|
@@ -454,6 +491,10 @@ begin
|
|
SaveJpeg;
|
|
SaveJpeg;
|
|
ModalResult := mrOK;
|
|
ModalResult := mrOK;
|
|
end;
|
|
end;
|
|
|
|
+ ifWebP: begin
|
|
|
|
+ SaveWebP;
|
|
|
|
+ ModalResult := mrOK;
|
|
|
|
+ end;
|
|
ifBmp:
|
|
ifBmp:
|
|
begin
|
|
begin
|
|
SaveBmp;
|
|
SaveBmp;
|
|
@@ -489,6 +530,12 @@ begin
|
|
NeedBitmapUpdate(True);
|
|
NeedBitmapUpdate(True);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TFSaveOption.CheckBox_LosslessChange(Sender: TObject);
|
|
|
|
+begin
|
|
|
|
+ if FInit then exit;
|
|
|
|
+ WebPQualityChanged;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TFSaveOption.Edit_QualityValueExit(Sender: TObject);
|
|
procedure TFSaveOption.Edit_QualityValueExit(Sender: TObject);
|
|
begin
|
|
begin
|
|
if FInit then exit;
|
|
if FInit then exit;
|
|
@@ -519,6 +566,11 @@ begin
|
|
FreeAndNil(FBmpStream);
|
|
FreeAndNil(FBmpStream);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TFSaveOption.GetLosslessVisible: boolean;
|
|
|
|
+begin
|
|
|
|
+ result := FLosslessVisible;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TFSaveOption.GetPngStreamNeeded: boolean;
|
|
function TFSaveOption.GetPngStreamNeeded: boolean;
|
|
begin
|
|
begin
|
|
result := (ImageFormat = ifPng) or
|
|
result := (ImageFormat = ifPng) or
|
|
@@ -527,6 +579,11 @@ begin
|
|
((FFlattenedOriginal.XorMask = nil) or FFlattenedOriginal.XorMask.Empty) );
|
|
((FFlattenedOriginal.XorMask = nil) or FFlattenedOriginal.XorMask.Empty) );
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TFSaveOption.GetWebPLossless: boolean;
|
|
|
|
+begin
|
|
|
|
+ result := CheckBox_Lossless.Checked;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TFSaveOption.UpdateQualityTextBox;
|
|
procedure TFSaveOption.UpdateQualityTextBox;
|
|
begin
|
|
begin
|
|
FInit := true;
|
|
FInit := true;
|
|
@@ -596,6 +653,33 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TFSaveOption.GetWebPPreview: TBGRABitmap;
|
|
|
|
+begin
|
|
|
|
+ RequireWebPStream;
|
|
|
|
+ if not Assigned(FWebPPreview) then
|
|
|
|
+ begin
|
|
|
|
+ FWebPPreview := TBGRABitmap.Create;
|
|
|
|
+ FWebPStream.Position := 0;
|
|
|
|
+ FWebPPreview.LoadFromStream(FWebPStream);
|
|
|
|
+ end;
|
|
|
|
+ result := FWebPPreview;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TFSaveOption.RequireWebPStream;
|
|
|
|
+var writer: TBGRAWriterWebP;
|
|
|
|
+begin
|
|
|
|
+ if not Assigned(FWebPStream) then
|
|
|
|
+ begin
|
|
|
|
+ FWebPStream := TMemoryStream.Create;
|
|
|
|
+ writer := TBGRAWriterWebP.Create;
|
|
|
|
+ writer.QualityPercent := JpegQuality;
|
|
|
|
+ writer.Lossless:= WebPLossless;
|
|
|
|
+ FFlattenedOriginal.SaveToStream(FWebPStream, writer);
|
|
|
|
+ writer.Free;
|
|
|
|
+ UpdateFileSize;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TFSaveOption.MakeBmpStreamIfNeeded;
|
|
procedure TFSaveOption.MakeBmpStreamIfNeeded;
|
|
begin
|
|
begin
|
|
if RadioButton_MioMap.Checked then
|
|
if RadioButton_MioMap.Checked then
|
|
@@ -636,6 +720,18 @@ begin
|
|
FInit := oldInit;
|
|
FInit := oldInit;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TFSaveOption.SetLosslessVisible(AValue: boolean);
|
|
|
|
+begin
|
|
|
|
+ if FLosslessVisible = AValue then exit;
|
|
|
|
+ FLosslessVisible := AValue;
|
|
|
|
+ CheckBox_Lossless.Visible := FLosslessVisible;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TFSaveOption.SetWebPLossless(AValue: boolean);
|
|
|
|
+begin
|
|
|
|
+ CheckBox_Lossless.Checked := AValue;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TFSaveOption.UpdateFileSize;
|
|
procedure TFSaveOption.UpdateFileSize;
|
|
var size: int64;
|
|
var size: int64;
|
|
begin
|
|
begin
|
|
@@ -666,6 +762,10 @@ begin
|
|
UpdateFileSizeTo(-1)
|
|
UpdateFileSizeTo(-1)
|
|
else
|
|
else
|
|
UpdateFileSizeTo(FJpegStream.Size);
|
|
UpdateFileSizeTo(FJpegStream.Size);
|
|
|
|
+ ifWebP: if FWebPStream = nil then
|
|
|
|
+ UpdateFileSizeTo(-1)
|
|
|
|
+ else
|
|
|
|
+ UpdateFileSizeTo(FWebPStream.Size);
|
|
ifPng: if FPngStream = nil then
|
|
ifPng: if FPngStream = nil then
|
|
UpdateFileSizeTo(-1)
|
|
UpdateFileSizeTo(-1)
|
|
else
|
|
else
|
|
@@ -701,7 +801,8 @@ var origBPP: integer;
|
|
begin
|
|
begin
|
|
if FImageFormat=AValue then Exit;
|
|
if FImageFormat=AValue then Exit;
|
|
FImageFormat:=AValue;
|
|
FImageFormat:=AValue;
|
|
- QualityVisible := FImageFormat = ifJpeg;
|
|
|
|
|
|
+ QualityVisible := FImageFormat in[ifJpeg, ifWebP];
|
|
|
|
+ LosslessVisible := (FImageFormat = ifWebP);
|
|
BitsPerPixelVisible := FImageFormat in[ifPng,ifBmp,ifIco,ifCur];
|
|
BitsPerPixelVisible := FImageFormat in[ifPng,ifBmp,ifIco,ifCur];
|
|
if FInit then exit;
|
|
if FInit then exit;
|
|
FInit := true;
|
|
FInit := true;
|
|
@@ -792,8 +893,12 @@ begin
|
|
FLazPaintInstance:=AValue;
|
|
FLazPaintInstance:=AValue;
|
|
FreeAndNil(FQuantizer);
|
|
FreeAndNil(FQuantizer);
|
|
FreeAndNil(FQuantizer1bit);
|
|
FreeAndNil(FQuantizer1bit);
|
|
|
|
+ FreeAndNil(FJpegStream);
|
|
FreeAndNil(FJpegPreview);
|
|
FreeAndNil(FJpegPreview);
|
|
|
|
+ FreeAndNil(FWebPStream);
|
|
|
|
+ FreeAndNil(FWebPPreview);
|
|
JpegQuality := FLazPaintInstance.Config.DefaultJpegQuality;
|
|
JpegQuality := FLazPaintInstance.Config.DefaultJpegQuality;
|
|
|
|
+ WebPLossless := FLazPaintInstance.Config.DefaultWebPLossless;
|
|
FFlattenedOriginal := FLazPaintInstance.Image.RenderedImage;
|
|
FFlattenedOriginal := FLazPaintInstance.Image.RenderedImage;
|
|
UpdateFileSize;
|
|
UpdateFileSize;
|
|
if LazPaintInstance.Config.DefaultSaveOptionDialogMaximized then
|
|
if LazPaintInstance.Config.DefaultSaveOptionDialogMaximized then
|
|
@@ -862,6 +967,16 @@ procedure TFSaveOption.JpegQualityChanged;
|
|
begin
|
|
begin
|
|
FreeAndNil(FJpegPreview);
|
|
FreeAndNil(FJpegPreview);
|
|
FreeAndNil(FJpegStream);
|
|
FreeAndNil(FJpegStream);
|
|
|
|
+ FreeAndNil(FWebPPreview);
|
|
|
|
+ FreeAndNil(FWebPStream);
|
|
|
|
+ UpdateFileSize;
|
|
|
|
+ NeedBitmapUpdate(False);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TFSaveOption.WebPQualityChanged;
|
|
|
|
+begin
|
|
|
|
+ FreeAndNil(FWebPPreview);
|
|
|
|
+ FreeAndNil(FWebPStream);
|
|
UpdateFileSize;
|
|
UpdateFileSize;
|
|
NeedBitmapUpdate(False);
|
|
NeedBitmapUpdate(False);
|
|
end;
|
|
end;
|