type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure ImageRotate90(aBitmap: TBitmap);
function GetPixelSize(aBitmap: TBitmap): Integer;
end;
var
Form1: TForm1;
const
BitsPerByte = 8; // Assume there are 8 bits in one byte, this may not be true in the future. (JIC)
implementation
{$R *.DFM}
{ this functions returns the number of bytes needed to represent 1 pixel
in the current PixelFormat of the bitmap. }
function TForm1.GetPixelSize(aBitmap: TBitmap): Integer;
var
nBitCount, nMultiplier: Integer;
begin
case aBitmap.PixelFormat of
pfDevice : begin
nBitCount := GetDeviceCaps(aBitmap.Canvas.Handle, BITSPIXEL);
nMultiplier := nBitCount div BitsPerByte;
if (nBitCount mod BitsPerByte)>0 then
begin
Inc(nMultiplier);
end;
end;
pf1bit : nMultiplier := 1;
pf4bit : nMultiplier := 1;
pf8bit : nMultiplier := 1;
pf15bit : nMultiplier := 2;
pf16bit : nMultiplier := 2;
pf24bit : nMultiplier := 3;
pf32bit : nMultiplier := 4;
else
//raise EInvalidPixelFormat.Create('Bitmap pixelformat is unknown.');
nMultiplier := 2;
end;
Result := nMultiplier;
end;
procedure TForm1.ImageRotate90(aBitmap: TBitmap);
var
nIdx, nOfs,
x, y, i,
nMultiplier: integer;
nMemWidth, nMemHeight, nMemSize,
nScanLineSize: LongInt;
GetMem(aScnLnBuffer, nMemSize);
try
nScanLineSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nScanLineSize);
try
for y := 0 to aBitmap.Height-1 do
begin
Move(aBitmap.ScanLine[y]^, aScanLine^, nScanLineSize);
for x := 0 to aBitmap.Width-1 do
begin
nIdx := ((aBitmap.Width-1) - x) * nMultiplier;
// y component of the dst x component of the dst
nOfs := (x * nMemWidth * nMultiplier) + (y * nMultiplier);
for i := 0 to nMultiplier-1 do
Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];
end;
end;
for y := 0 to nMemHeight-1 do
begin
nOfs := y * nMemWidth * nMultiplier;
Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);
end;
finally
FreeMem(aScanLine, nScanLineSize);
end;
finally
FreeMem(aScnLnBuffer, nMemSize);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
BMP : TBitMap;
begin
BMP := TBitMap.Create;
try
BMP.LoadFromFile('c:\temp\바탕그림.bmp');
ImageRotate90(BMP);
BMP.SaveToFile('c:\temp\바탕그림1.bmp');
finally
BMP.Free;
end;
end;
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
EInvalidPixelFormat = class(Exception);
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure ImageRotate90(aBitmap: TBitmap);
function GetPixelSize(aBitmap: TBitmap): Integer;
end;
var
Form1: TForm1;
const
BitsPerByte = 8; // Assume there are 8 bits in one byte, this may not be true in the future. (JIC)
implementation
{$R *.DFM}
{ this functions returns the number of bytes needed to represent 1 pixel
in the current PixelFormat of the bitmap. }
function TForm1.GetPixelSize(aBitmap: TBitmap): Integer;
var
nBitCount, nMultiplier: Integer;
begin
case aBitmap.PixelFormat of
pfDevice : begin
nBitCount := GetDeviceCaps(aBitmap.Canvas.Handle, BITSPIXEL);
nMultiplier := nBitCount div BitsPerByte;
if (nBitCount mod BitsPerByte)>0 then
begin
Inc(nMultiplier);
end;
end;
pf1bit : nMultiplier := 1;
pf4bit : nMultiplier := 1;
pf8bit : nMultiplier := 1;
pf15bit : nMultiplier := 2;
pf16bit : nMultiplier := 2;
pf24bit : nMultiplier := 3;
pf32bit : nMultiplier := 4;
else
//raise EInvalidPixelFormat.Create('Bitmap pixelformat is unknown.');
nMultiplier := 2;
end;
Result := nMultiplier;
end;
procedure TForm1.ImageRotate90(aBitmap: TBitmap);
var
nIdx, nOfs,
x, y, i,
nMultiplier: integer;
nMemWidth, nMemHeight, nMemSize,
nScanLineSize: LongInt;
aScnLnBuffer: PChar;
aScanLine: PByteArray;
begin
nMultiplier := GetPixelSize(ABitmap);
nMemWidth := aBitmap.Height;
nMemHeight := aBitmap.Width;
nMemSize := nMemWidth * nMemHeight * nMultiplier;
GetMem(aScnLnBuffer, nMemSize);
try
nScanLineSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nScanLineSize);
try
for y := 0 to aBitmap.Height-1 do
begin
Move(aBitmap.ScanLine[y]^, aScanLine^, nScanLineSize);
for x := 0 to aBitmap.Width-1 do
begin
nIdx := ((aBitmap.Width-1) - x) * nMultiplier;
// y component of the dst x component of the dst
nOfs := (x * nMemWidth * nMultiplier) + (y * nMultiplier);
for i := 0 to nMultiplier-1 do
Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];
end;
end;
aBitmap.Height := nMemHeight;
aBitmap.Width := nMemWidth;
for y := 0 to nMemHeight-1 do
begin
nOfs := y * nMemWidth * nMultiplier;
Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);
end;
finally
FreeMem(aScanLine, nScanLineSize);
end;
finally
FreeMem(aScnLnBuffer, nMemSize);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
BMP : TBitMap;
begin
BMP := TBitMap.Create;
try
BMP.LoadFromFile('c:\temp\바탕그림.bmp');
ImageRotate90(BMP);
BMP.SaveToFile('c:\temp\바탕그림1.bmp');
finally
BMP.Free;
end;
end;
end.