mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: Viewer - fast rotate and mirror functions for 32 bit images
This commit is contained in:
parent
3666aba90b
commit
de6219e1e6
2 changed files with 219 additions and 97 deletions
109
src/fviewer.pas
109
src/fviewer.pas
|
|
@ -464,8 +464,8 @@ type
|
|||
function DoZoom( const delta: Double; const inc: Integer ): Boolean;
|
||||
function DoZoomIn: Boolean;
|
||||
function DoZoomOut: Boolean;
|
||||
procedure RotateImage(AGradus:integer);
|
||||
procedure MirrorImage(AVertically:boolean=False);
|
||||
procedure RotateImage(ADegree: Integer);
|
||||
procedure MirrorImage(AVertically: Boolean = False);
|
||||
|
||||
published
|
||||
// Commands for hotkey manager
|
||||
|
|
@ -542,7 +542,7 @@ uses
|
|||
uConvEncoding, DCBasicTypes, DCOSUtils, uOSUtils, uFindByrMr, uFileViewWithGrid,
|
||||
fPrintSetup, uFindFiles, uAdministrator, uOfficeXML, uHighlighterProcs, dmHigh,
|
||||
SynEditTypes, uFile, uFileSystemFileSource, uFileProcs, uOperationsManager,
|
||||
uFileSourceOperationOptions, uGraphics
|
||||
LazLogger, uFileSourceOperationOptions, uGraphics
|
||||
{$if lcl_fullversion >= 4990000}
|
||||
, SynEditWrappedView
|
||||
{$endif}
|
||||
|
|
@ -1908,106 +1908,25 @@ begin
|
|||
Result:= DoZoom( 0.909, -1 );
|
||||
end;
|
||||
|
||||
procedure TfrmViewer.RotateImage(AGradus: integer);
|
||||
// AGradus now supported only 90,180,270 values
|
||||
procedure TfrmViewer.RotateImage(ADegree: integer);
|
||||
// ADegree now supported only 90,180,270 values
|
||||
var
|
||||
x, y: Integer;
|
||||
xWidth,
|
||||
yHeight: Integer;
|
||||
SourceImg: TLazIntfImage;
|
||||
TargetImg: TLazIntfImage;
|
||||
Q: QWord;
|
||||
begin
|
||||
TargetImg:= TLazIntfImage.Create(0, 0);
|
||||
SourceImg := TLazIntfImage.Create(TRasterImage(Image.Picture.Graphic).RawImage, False);
|
||||
TargetImg.DataDescription:= SourceImg.DataDescription; // use the same image format
|
||||
xWidth:= SourceImg.Width - 1;
|
||||
yHeight:= SourceImg.Height - 1;
|
||||
|
||||
if AGradus = 90 then
|
||||
begin
|
||||
TargetImg.SetSize(yHeight + 1, xWidth + 1);
|
||||
for y:= 0 to xWidth do
|
||||
begin
|
||||
for x:= 0 to yHeight do
|
||||
begin
|
||||
TargetImg.Colors[x, y]:= SourceImg.Colors[y, yHeight - x];
|
||||
end;
|
||||
end;
|
||||
x:= Image.Width;
|
||||
Image.Width:= Image.Height;
|
||||
Image.Height:= x;
|
||||
end;
|
||||
|
||||
if AGradus = 180 then
|
||||
begin
|
||||
TargetImg.SetSize(xWidth + 1, yHeight + 1);
|
||||
for y:= 0 to yHeight do
|
||||
begin
|
||||
for x:= 0 to xWidth do
|
||||
begin
|
||||
TargetImg.Colors[x, y]:= SourceImg.Colors[xWidth - x, yHeight - y];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if AGradus = 270 then
|
||||
begin
|
||||
TargetImg.SetSize(yHeight + 1, xWidth + 1);
|
||||
for y:= 0 to xWidth do
|
||||
begin
|
||||
for x:= 0 to yHeight do
|
||||
begin
|
||||
TargetImg.Colors[x, y]:= SourceImg.Colors[xWidth - y, x];
|
||||
end;
|
||||
end;
|
||||
x:= Image.Width;
|
||||
Image.Width:= Image.Height;
|
||||
Image.Height:= x;
|
||||
end;
|
||||
|
||||
BitmapAssign(TRasterImage(Image.Picture.Graphic), TargetImg);
|
||||
|
||||
FreeAndNil(SourceImg);
|
||||
FreeAndNil(TargetImg);
|
||||
Q:= SysUtils.GetTickCount64;
|
||||
BitmapRotate(TRasterImage(Image.Picture.Graphic), ADegree);
|
||||
DebugLn('Rotate: ', IntToStr(SysUtils.GetTickCount64 - Q));
|
||||
AdjustImageSize;
|
||||
CreateTmp;
|
||||
end;
|
||||
|
||||
procedure TfrmViewer.MirrorImage(AVertically:boolean);
|
||||
procedure TfrmViewer.MirrorImage(AVertically: Boolean);
|
||||
var
|
||||
x, y: Integer;
|
||||
xWidth,
|
||||
yHeight: Integer;
|
||||
SourceImg: TLazIntfImage;
|
||||
TargetImg: TLazIntfImage;
|
||||
Q: QWord;
|
||||
begin
|
||||
TargetImg:= TLazIntfImage.Create(0, 0);
|
||||
SourceImg := TLazIntfImage.Create(TRasterImage(Image.Picture.Graphic).RawImage, False);
|
||||
TargetImg.DataDescription:= SourceImg.DataDescription; // use the same image format
|
||||
xWidth:= SourceImg.Width - 1;
|
||||
yHeight:= SourceImg.Height - 1;
|
||||
|
||||
if not AVertically then
|
||||
for y:= 0 to yHeight do
|
||||
begin
|
||||
for x:= 0 to xWidth do
|
||||
begin
|
||||
TargetImg.Colors[x, y]:= SourceImg.Colors[xWidth - x, y];
|
||||
end;
|
||||
end
|
||||
else
|
||||
for y:= 0 to yHeight do
|
||||
begin
|
||||
for x:= 0 to xWidth do
|
||||
begin
|
||||
TargetImg.Colors[x, y]:= SourceImg.Colors[ x,yHeight - y];
|
||||
end;
|
||||
end;
|
||||
|
||||
BitmapAssign(TRasterImage(Image.Picture.Graphic), TargetImg);
|
||||
|
||||
FreeAndNil(SourceImg);
|
||||
FreeAndNil(TargetImg);
|
||||
Q:= SysUtils.GetTickCount64;
|
||||
BitmapMirror(TRasterImage(Image.Picture.Graphic), AVertically);
|
||||
DebugLn('Mirror: ', IntToStr(SysUtils.GetTickCount64 - Q));
|
||||
AdjustImageSize;
|
||||
CreateTmp;
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ procedure BitmapConvert(Bitmap: TRasterImage);
|
|||
procedure BitmapAssign(Bitmap, Image: TRasterImage);
|
||||
procedure BitmapConvert(ASource, ATarget: TRasterImage);
|
||||
procedure BitmapAlpha(var ABitmap: TBitmap; APercent: Single);
|
||||
procedure BitmapRotate(Bitmap: TRasterImage; ADegree: Integer);
|
||||
procedure BitmapMirror(Bitmap: TRasterImage; AVertically: Boolean);
|
||||
procedure BitmapAssign(Bitmap: TRasterImage; Image: TLazIntfImage);
|
||||
procedure BitmapCenter(var Bitmap: TBitmap; Width, Height: Integer);
|
||||
procedure BitmapMerge(ALow, AHigh: TLazIntfImage; const ADestX, ADestY: Integer);
|
||||
|
|
@ -82,6 +84,207 @@ begin
|
|||
RawImage^.ReleaseData;
|
||||
end;
|
||||
|
||||
procedure BitmapRotate(Bitmap: TRasterImage; ADegree: Integer);
|
||||
// ADegree now supported only 90,180,270 values
|
||||
var
|
||||
x, y: Integer;
|
||||
tx, ty: Integer;
|
||||
Bits32: Boolean;
|
||||
xWidth, yHeight: Integer;
|
||||
iWidth, iHeight: Integer;
|
||||
SourceImg: TLazIntfImage;
|
||||
TargetImg: TLazIntfImage;
|
||||
SourceData, TargetData: PUInt32;
|
||||
begin
|
||||
TargetImg:= TLazIntfImage.Create(0, 0);
|
||||
SourceImg := TLazIntfImage.Create(Bitmap.RawImage, False);
|
||||
TargetImg.DataDescription:= SourceImg.DataDescription; // use the same image format
|
||||
iWidth:= SourceImg.Width;
|
||||
iHeight:= SourceImg.Height;
|
||||
xWidth:= iWidth - 1;
|
||||
yHeight:= iHeight - 1;
|
||||
|
||||
// Use fast 32 bit rotate function
|
||||
Bits32:= (SourceImg.DataDescription.BitsPerPixel = 32) and
|
||||
(SourceImg.DataDescription.LineOrder = riloTopToBottom) and
|
||||
(SourceImg.DataDescription.LineEnd < rileQWordBoundary);
|
||||
if Bits32 then
|
||||
begin
|
||||
SourceData:= PUInt32(SourceImg.PixelData);
|
||||
TargetData:= PUInt32(TargetImg.PixelData);
|
||||
end;
|
||||
|
||||
if ADegree = 90 then
|
||||
begin
|
||||
TargetImg.SetSize(iHeight, iWidth);
|
||||
if Bits32 then
|
||||
begin
|
||||
for y:= 0 to yHeight do
|
||||
begin
|
||||
ty:= yHeight - y;
|
||||
for x:= 0 to xWidth do
|
||||
begin
|
||||
TargetData[iHeight * x + ty]:= SourceData^;
|
||||
Inc(SourceData);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
for y:= 0 to xWidth do
|
||||
begin
|
||||
for x:= 0 to yHeight do
|
||||
begin
|
||||
TargetImg.Colors[x, y]:= SourceImg.Colors[y, yHeight - x];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
|
||||
else if ADegree = 180 then
|
||||
begin
|
||||
TargetImg.SetSize(iWidth, iHeight);
|
||||
|
||||
if Bits32 then
|
||||
begin
|
||||
for y:= 0 to yHeight do
|
||||
begin
|
||||
ty:= yHeight - y;
|
||||
for x:= 0 to xWidth do
|
||||
begin
|
||||
tx:= xWidth - x;
|
||||
TargetData[iWidth * ty + tx]:= SourceData^;
|
||||
Inc(SourceData);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
for y:= 0 to yHeight do
|
||||
begin
|
||||
for x:= 0 to xWidth do
|
||||
begin
|
||||
TargetImg.Colors[x, y]:= SourceImg.Colors[xWidth - x, yHeight - y];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
|
||||
else if ADegree = 270 then
|
||||
begin
|
||||
TargetImg.SetSize(iHeight, iWidth);
|
||||
if Bits32 then
|
||||
begin
|
||||
for y:= 0 to yHeight do
|
||||
begin
|
||||
for x:= 0 to xWidth do
|
||||
begin
|
||||
tx:= xWidth - x;
|
||||
TargetData[iHeight * tx + y]:= SourceData^;
|
||||
Inc(SourceData);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
for y:= 0 to xWidth do
|
||||
begin
|
||||
for x:= 0 to yHeight do
|
||||
begin
|
||||
TargetImg.Colors[x, y]:= SourceImg.Colors[xWidth - y, x];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
BitmapAssign(Bitmap, TargetImg);
|
||||
|
||||
FreeAndNil(SourceImg);
|
||||
FreeAndNil(TargetImg);
|
||||
end;
|
||||
|
||||
procedure BitmapMirror(Bitmap: TRasterImage; AVertically: Boolean);
|
||||
var
|
||||
x, y: Integer;
|
||||
tx, ty: Integer;
|
||||
Bits32: Boolean;
|
||||
xWidth, yHeight: Integer;
|
||||
iWidth, iHeight: Integer;
|
||||
SourceImg: TLazIntfImage;
|
||||
TargetImg: TLazIntfImage;
|
||||
SourceData, TargetData: PUInt32;
|
||||
begin
|
||||
TargetImg:= TLazIntfImage.Create(0, 0);
|
||||
SourceImg := TLazIntfImage.Create(Bitmap.RawImage, False);
|
||||
TargetImg.DataDescription:= SourceImg.DataDescription; // use the same image format
|
||||
iWidth:= SourceImg.Width;
|
||||
iHeight:= SourceImg.Height;
|
||||
xWidth:= iWidth - 1;
|
||||
yHeight:= iHeight - 1;
|
||||
|
||||
|
||||
// Use fast 32 bit mirror function
|
||||
Bits32:= (SourceImg.DataDescription.BitsPerPixel = 32) and
|
||||
(SourceImg.DataDescription.LineOrder = riloTopToBottom) and
|
||||
(SourceImg.DataDescription.LineEnd < rileQWordBoundary);
|
||||
if Bits32 then
|
||||
begin
|
||||
SourceData:= PUInt32(SourceImg.PixelData);
|
||||
TargetData:= PUInt32(TargetImg.PixelData);
|
||||
end;
|
||||
|
||||
if not AVertically then
|
||||
begin
|
||||
if Bits32 then
|
||||
begin
|
||||
for y:= 0 to yHeight do
|
||||
begin
|
||||
ty:= iWidth * y;
|
||||
for x:= 0 to xWidth do
|
||||
begin
|
||||
tx:= xWidth - x;
|
||||
TargetData[ty + tx]:= SourceData^;
|
||||
Inc(SourceData);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
for y:= 0 to yHeight do
|
||||
begin
|
||||
for x:= 0 to xWidth do
|
||||
begin
|
||||
TargetImg.Colors[x, y]:= SourceImg.Colors[xWidth - x, y];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
if Bits32 then
|
||||
begin
|
||||
for y:= 0 to yHeight do
|
||||
begin
|
||||
ty:= iWidth * (yHeight - y);
|
||||
for x:= 0 to xWidth do
|
||||
begin
|
||||
TargetData[ty + x]:= SourceData^;
|
||||
Inc(SourceData);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
for y:= 0 to yHeight do
|
||||
begin
|
||||
for x:= 0 to xWidth do
|
||||
begin
|
||||
TargetImg.Colors[x, y]:= SourceImg.Colors[x, yHeight - y];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
BitmapAssign(Bitmap, TargetImg);
|
||||
|
||||
FreeAndNil(SourceImg);
|
||||
FreeAndNil(TargetImg);
|
||||
end;
|
||||
|
||||
procedure BitmapAssign(Bitmap: TRasterImage; Image: TLazIntfImage);
|
||||
var
|
||||
ARawImage: TRawImage;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue