Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 299
  • Last Modified:

Reduction of JPeg Bitmap

How do I propotionally reduce a the width of a jpeg fiele from 2240 pixels to 120 pixels
0
Vector7
Asked:
Vector7
  • 2
2 Solutions
 
shaneholmesCommented:
Try this:

Procedure ScaleDownJPG(Fname:string;newheight,newWidth:integer) ;
var JPG1,JPG2:TJpegImage;
    BMP:Tbitmap;
Begin
  try
     JPG1:=TJpegimage.create;
     JPG2:=TJpegimage.create;
     BMP:=Tbitmap.create;
     Jpg1.LoadFromFile(Fname);
     With BMP do
     begin
       height:=newheight;
       Width:=newWidth;
       canvas.stretchdraw(canvas.cliprect,jpg1);
     end;
     bmp.savetofile('Z:\test.bmp');
     JPG2.assign(BMP);
     DeleteFile(fname);
     Jpg2.savetofile(fname);
   finally
     Jpg1.free;
     Jpg2.free;
     BMP.free;
   end;
end;

Shane
0
 
Vector7Author Commented:
Thanks Shane.  I've tried this and it works - many thanks.  However, how do you preserve a degree of quality? Stephen
0
 
shaneholmesCommented:
I found this on Google Groups: Give it a try!

Shane


I do not really understand what you are getting at, but I assmue the
problem is that you are changing the Size of the Timage, assuming that
will rescale the image?
Well resizing a TImage will make the image look rescaled, but it does
NOT rescale the underlining bitmap that is stored in the TImage.

Also stretchdraw does not give as agood a resized quality (i.e. does no
resampling).

Try the following SmoothResize code.
It requires 24-bit bitmaps and D3 or higher.  
Call it with something like:

  SmoothResize(Image1.Picture.Bitmap,NewImage1Width,NewImageHeight);
  Image1.Refresh;

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

procedure SmoothResize(abmp:TBitmap; NuWidth,NuHeight:integer);
var
   weight_x, weight_y     : array[0..1] of Single;
   ifrom_y, ifrom_x       : Integer;
   to_y, to_x             : Integer;
   new_red, new_green     : Integer;
   new_blue               : Integer;
   ix, iy                 : Integer;
   xscale, yscale         : Single;
   sfrom_y, sfrom_x       : Single;
   weight                 : Single;
   total_red, total_green : Single;
   total_blue             : Single;
   bTmp                   : TBitmap;
   sli, slo               : pRGBArray;
   // pointers for scanline access
   liPByte, loPByte, p    : PByte;
   // offset increment
   liSize, loSize         : integer;
begin
   abmp.PixelFormat := pf24bit;
   bTmp := TBitmap.Create;
   bTmp.PixelFormat := pf24bit;
   bTmp.Width := NuWidth;
   bTmp.Height := NuHeight;
   xscale := bTmp.Width / (abmp.Width-1);
   yscale := bTmp.Height / (abmp.Height-1);
   liPByte := abmp.Scanline[0];
   liSize := integer(abmp.Scanline[1]) -integer(liPByte);
   loPByte := bTmp.Scanline[0];
   loSize := integer(bTmp.Scanline[1]) -integer(loPByte);
   for to_y := 0 to bTmp.Height-1 do begin
     sfrom_y := to_y / yscale;
     ifrom_y := Trunc(sfrom_y);
     weight_y[1] := sfrom_y - ifrom_y;
     weight_y[0] := 1 - weight_y[1];
     for to_x := 0 to bTmp.Width-1 do begin
       sfrom_x := to_x / xscale;
       ifrom_x := Trunc(sfrom_x);
       weight_x[1] := sfrom_x - ifrom_x;
       weight_x[0] := 1 - weight_x[1];
       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
           p := liPByte;
           Inc(p, liSize *(ifrom_y + iy));
           sli := pRGBArray(p);
           new_red := sli[ifrom_x + ix].rgbtRed;
           new_green := sli[ifrom_x + ix].rgbtGreen;
           new_blue := sli[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;
       p := loPByte;
       Inc(p, loSize *to_y);
       slo := pRGBArray(p);
       slo[to_x].rgbtRed := Round(total_red);
       slo[to_x].rgbtGreen := Round(total_green);
       slo[to_x].rgbtBlue := Round(total_blue);
     end;
   end;
   abmp.Width := bTmp.Width;
   abmp.Height := bTmp.Height;
   abmp.Canvas.Draw(0,0,bTmp);
   bTmp.Free;
end;

--
Charles Hacker
Lecturer in Electronics and Computing
School of Engineering
Griffith University - Gold Coast
Australia
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

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