• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 488
  • Last Modified:

How to rotate JPG image?

Hi all,

I have a stream data of JPG picture. If I want to rotate(180 degree) the image and then save it to the old stream, how can I do?

All source code examples are highly appreciated.

Thanks in advance,
Peerapol
0
Mr_Peerapol
Asked:
Mr_Peerapol
1 Solution
 
kretzschmarCommented:
hi mr peerapol,

maybe this helps

http://www.efg2.com/lab/imageprocessing/RotateScanline.htm

meikl
0
 
mhervaisCommented:
great lib Kretzschmar
0
 
kretzschmarCommented:
hi again,

another solution

procedure TForm1.Button1Click(Sender: TObject);
var
  JImage : TJpegImage;
  BImageSource, BImageDest : TBitmap;
begin
  JImage := TJpegImage.Create;
  BImageSource := TBitmap.Create;
  BImageDest   := TBitmap.Create;
  Try
    JImage.LoadFromFile('c:\Test.jpg'); //or from the stream
    BImageSource.Assign(JImage);
    BImageDest.Height := BImageSource.Height;
    BImageDest.Width := BImageSource.Width;
    BImageDest.Canvas.StretchDraw(Rect(BImageSource.Width,
                                       BImageSource.Height,
                                       0,0),BImageSource);
    JImage.Assign(BImageDest);
    JImage.CompressionQuality := 75;  //Default = 90, adjust if other
    JImage.Compress;
    JImage.SaveToFile('c:\Test180.jpg'); //or to the stream
  finally
    JImage.Free;
    BImageSource.Free;
    BImageDest.Free;
  end;
end;

meikl
0
 
intheCommented:
Hi
Here's a complete unit that shows how to rotate a 24-bit bitmap with anti-aliasing and edge wrapping. It uses Scanline, so needs D3 or D4 to compile. It's bare bones (no error checking), and not optimized ,To recreate this, drop an Image and a button on a form and load the image with a picture (Make the image Autosize true). This is a modification of code by Rod Stephens in the 11/98 issue of Delphi Informant.


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;

type
TRGBArray = ARRAY[0..32767] OF TRGBTriple;
pRGBArray = ^TRGBArray;

type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
bmpNorm, bmpRotated : TBitmap;
procedure RotateAngle(Angle: integer; bFrom, bTo : TBitmap); public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
bmpNorm := TBitmap.Create;
bmpNorm.Width := Image1.Width;
bmpNorm.Height := Image1.Height;
bmpNorm.PixelFormat := pf24bit;
bmpRotated := TBitmap.Create;
bmpRotated.Width := Image1.Width;
bmpRotated.Height := Image1.Height;
bmpRotated.PixelFormat := pf24bit;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
bmpNorm.Canvas.Draw(0,0,Image1.Picture.Graphic);
RotateAngle(35,bmpNorm,bmpRotated);
Image1.Picture.Assign(bmpRotated);
end;

procedure TForm1.RotateAngle(Angle: integer; bFrom, bTo : TBitmap); var
Theta, cosTheta, sinTheta: Single;
cx, cy : Single; //Center X, Y
sfrom_y, sfrom_x : Single; //Real number
ifrom_y, ifrom_x : Integer; //Integer version
to_y, to_x : Integer;
weight_x, weight_y : array[0..1] of Single;
weight : Single;
new_red, new_green : Integer;
new_blue : Integer;
total_red, total_green : Single;
total_blue : Single;
ix, iy : Integer;
pb, pc : pRGBArray;
begin
Screen.Cursor := crHourGlass;
// Calculate the sine and cosine of theta for later.
Theta:=-(Angle)*Pi/180;
sinTheta:=Sin(Theta);
cosTheta:=Cos(Theta);
cx := bFrom.Width / 2;
cy := bFrom.Height / 2;
// Perform the rotation.
for to_y := 0 to bTo.Height-1 do begin
for to_x := 0 to bTo.Width-1 do begin
// Find the location (from_x, from_y) that
// rotates to position (to_x, to_y).
sfrom_x := cx +
(to_x - cx) * cosTheta -
(to_y - cy) * sinTheta;
ifrom_x := Trunc(sfrom_x);

sfrom_y := cy +
(to_x - cx) * sinTheta +
(to_y - cy) * cosTheta;
ifrom_y := Trunc(sfrom_y);

// Calculate the weights.
if sfrom_y >= 0 then begin
weight_y[1] := sfrom_y - ifrom_y;
weight_y[0] := 1 - weight_y[1];
end else begin
weight_y[0] := -(sfrom_y - ifrom_y);
weight_y[1] := 1 - weight_y[0];
end;
if sfrom_x >= 0 then begin
weight_x[1] := sfrom_x - ifrom_x;
weight_x[0] := 1 - weight_x[1];
end else begin
weight_x[0] := -(sfrom_x - ifrom_x);
Weight_x[1] := 1 - weight_x[0];
end;

if ifrom_x < 0 then
ifrom_x := bFrom.Width -1-(-ifrom_x mod bFrom.Width)
else if ifrom_x > bFrom.Width-1 then
ifrom_x := ifrom_x mod bFrom.Width;
if ifrom_y < 0 then
ifrom_y := bFrom.Height -1-(-ifrom_y mod bFrom.Height)
else if ifrom_y > bFrom.Height-1 then
ifrom_y := ifrom_y mod bFrom.Height;

// Average the color components of the four
// nearest pixels in from_canvas.
total_red := 0.0;
total_green := 0.0;
total_blue := 0.0;
for ix := 0 to 1 do begin
for iy := 0 to 1 do begin
if ifrom_y + iy < bFrom.Height then
pc := bFrom.ScanLine[ifrom_y + iy]
else
pc := bFrom.ScanLine[bFrom.Height - ifrom_y - iy]; if ifrom_x + ix < bFrom.Width then begin
new_red := pc[ifrom_x + ix].rgbtRed;
new_green := pc[ifrom_x + ix].rgbtGreen;
new_blue := pc[ifrom_x + ix].rgbtBlue;
weight := weight_x[ix] * weight_y[iy];
total_red := total_red + new_red * weight;
total_green := total_green + new_green * weight;
total_blue := total_blue + new_blue * weight;
end
else begin
new_red := pc[bFrom.Width - ifrom_x - ix].rgbtRed; new_green := pc[bFrom.Width - ifrom_x - ix].rgbtGreen; new_blue := pc[bFrom.Width - ifrom_x - ix].rgbtBlue; weight := weight_x[ix] * weight_y[iy];
total_red := total_red + new_red * weight;
total_green := total_green + new_green * weight;
total_blue := total_blue + new_blue * weight;
end;
end;
end;
pb := bTo.ScanLine[to_y];
pb[to_x].rgbtRed := Round(total_red);
pb[to_x].rgbtGreen := Round(total_green);
pb[to_x].rgbtBlue := Round(total_blue);
end;
end;
Screen.Cursor := crDefault;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
bmpNorm.Free;
bmpRotated.Free;
end;

end.


Regards Barry
0
 
PeterLarsenCommented:
Listening...
0

Featured Post

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now