Resizing jpg to smaller resolution

I am not sure whether I should be in C# or C++ perhaps somebody could advise

I write in Visual Basic & have an app the I want to allow the user to select some jpg files and have them reduced in resolution

As Vb does not have this facility, I was hoping I could get somone to point me in the direction a code example I could utilise in net 2005, (don't yet know how) using C which I could then compile.

my app would shell the c app at the appropriate time

or a compiled exe that does the following

read a text file which has detail re resizing size
a list of files to resize with destination folder and name

the app would then read my text file and resize the jpg to anothe folder

Any help much appreciated


Answer this question

Resizing jpg to smaller resolution

  • Andrew_J

    I gave a fuller answer to this same question here http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21460729.html

    but I will include some of the relevant text.

    private System.Drawing.Image GetImage(int _id) {
    //get image from your database etc
    return ret;
    }

    private int ReadVal(string name, int def) {
    int ret = def;
    if(Request.QueryString[name] != null) {
    try {
    ret = System.Convert.ToInt32(Request.QueryString[name]);
    }
    catch {}
    }
    return ret;
    }

    public bool ThumbnailCallback() {
    return false;
    }

    private void Page_Load(object sender, System.EventArgs e) {
    float x,y,newx,newy,deltax,deltay;
    float scale;
    int force;
    if(Request.QueryString["id"] == null) {
    throw new System.Exception("must have id") ;
    }
    System.Drawing.Image img = GetImage(System.Convert.ToInt32(Request.QueryString["id"]));
    x = ReadVal("x", img.Size.Width);
    y = ReadVal("y", img.Size.Height);
    force=ReadVal("force", 0);

    newx = img.Size.Width;
    newy = img.Size.Height;
    if(img.Size.Width > x || img.Size.Height > y || force == 1) {
    deltax = img.Size.Width - x;
    deltay = img.Size.Height - y;
    scale = deltax > deltay x / newx : y / newy;
    newx = newx * scale;
    newy = newy * scale;
    }

    if(newx != img.Size.Width) {
    System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
    img = img.GetThumbnailImage((int) newx,(int) newy,myCallback,IntPtr.Zero);
    }
    Response.ContentType = "image/jpeg" ;
    img.Save(Response.OutputStream, ImageFormat.Jpeg);
    }


    You will notice that this example is using GetThumbnailImage() ... this can cause problems if the images you are dealing with have embedded thumbnails

    for example ...

    I have an 800x600 image that I want to resize to 400x300 ...
    if I use GetThumbNailImage() and this image has a thumbnail image it will blow up the thumbnail image to 400x300 as opposed to shrinking the 800x600 to 400x300 ... this can cause alot of loss in your image or some funnier results in images due to the thumbnail not being the same as the original image!


    The following code does not have this problem but can execute slower in some circumstances.

    public System.Drawing.Image ResizeImage(System.Drawing.Image poImage, System.Drawing.Size poSize) {



    //Detach image from its source

    System.Drawing.Image oImageOriginal = (System.Drawing.Image)poImage.Clone();



    //Resize new image

    System.Drawing.Image oResizedImage = new System.Drawing.Bitmap(poSize.Width, poSize.Height, oImageOriginal.PixelFormat);

    System.Drawing.Graphics oGraphic = Graphics.FromImage(oResizedImage);

    oGraphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality ;

    oGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality ;

    oGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic ;

    Rectangle oRectangle = new Rectangle(0, 0, poSize.Width, poSize.Height);

    oGraphic.DrawImage(oImageOriginal, oRectangle);

    oGraphic.Dispose() ;

    oImageOriginal.Dispose();

    return oResizedImage;

    }


  • Peter Toye

    Thanks to both for replying, I will check it out this weekend

    nice to know people are willing to work across different language platforms

    Bob

  • weezer24

    Thanks

    Its not always easy to be aware of other traps that may occur, so I will take note of your suggestion

    Thanks again
    Bob

  • Lyn*

    Convert to what

    Have you tried the third bit You can alter the quality etc.

    Also GetThumbnailImage() is just a framework method ... you should be able to call it directly .. the rest of that code is handling aspect ratios etc.

    to use it you just need the following

    public bool ThumbnailCallback() {
    return false;
    }

    System.Drawing.Image.GetThumbnailImageAbort myCallback = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
    img = img.GetThumbnailImage((int) newx,(int) newy,myCallback,IntPtr.Zero);


  • Paully_l

    If you only want to give the user the ability to resize jpg files on harddisk then you can also install the image-resizer powertoy from microsoft and the user can do the resizing by right-clicking on the jpg file and select 'resize pictures'.

    http://www.microsoft.com/windowsxp/downloads/powertoys/xppowertoys.mspx

    Sandor


  • mojaveson

    I seem to be having some problems replying in this forum I am not used to

    Sorry for thinking you were 2 people

    I have converted the first set of code & Reduced a 4mb to 800kb but does not get any smaller regardless of size I specify

    Irfan view also reports image size same dimensions as original

    as for 2nd lot of code I am finding it difficult to convert

    Thanks for your help
    BOB

  • Emily Fong

     Greg Young wrote:

    heh they ere both me .. was trying to give a more complete answer :D


  • CRasmussen

    Thanks for this, with a few tweaks I have what I need, I am much appreciative of your help

    The end result is this:

    Public Sub ResizeImage(ByVal Image2Resize As String, ByVal Image2Resize2 As String, ByVal poSizeWidth As Integer, ByVal poSizeHeight As Integer)

    Dim poImage As Image = Image.FromFile(Image2Resize)
    Dim Original As Image = DirectCast(poImage.Clone(), Image)


    If Original.Height > Original.Width Then
    ' Portrait
    Dim TempValue As Integer
    TempValue = poSizeWidth
    poSizeWidth = poSizeHeight
    poSizeHeight = TempValue
    End If


    Dim ResizedImage As Image = New Bitmap(poSizeWidth, poSizeHeight, Original.PixelFormat)
    Dim oGraphic As Graphics = Graphics.FromImage(ResizedImage)
    Dim oRectangle As Rectangle = New Rectangle(0, 0, poSizeWidth, poSizeHeight)

    oGraphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality
    oGraphic.SmoothingMode = System.Drawing.Drawing2D.CompositingQuality.HighQuality
    oGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
    oGraphic.DrawImage(Original, oRectangle)

    oGraphic.Dispose()
    Original.Dispose()
    ResizedImage.Save(Image2Resize2, System.Drawing.Imaging.ImageFormat.Jpeg)


    End Sub

    Regards
    Bob

  • BaoMJ

    this code could also be used in VB.NET (slight translation)

    public Image resizeImage( Image img, int width, int height )
    {
    Bitmap bitmap = new Bitmap( width, height ) ;
    Graphics g = Graphics.FromImage( (Image ) bitmap ) ;

    g.DrawImage( img, 0, 0, width, height ) ;
    g.Dispose() ;

    return (Image ) b ;
    }


  • Omega147

    Sandor, thanks for this, I have downloaded it and will find it most useful when not using my app

    Regards
    Bob

  • Dominik Ras

    public function ResizeImage(byval poImage as Image, byval poSize as Size) as Image
    dim Original as Image = DirectCast(Image.Clone(), Image)
    dim ResizedImage as Image = new BitMap(poSize.Width, poSize.Height, Original.PixelFormat)
    dim oGraphic as Graphic = Graphics.FromImage(ResizedImage)
    oGraphic.CompositingQuality =
    System.Drawing.Drawing2D.CompositingQuality.HighQuality
    oGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
    oGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
    dim oRectangle as Rectange = new Rectangle(0,0, poSize.Width, poSize.Height)
    oGraphic.DrawImage(Original, oRectangle)
    oGraphic.Dispose()
    Original.Dispose()
    return ResizedImage
    end function

    I just did this here but it should be close for you.


  • King Interested in VB.NET

    heh they ere both me .. was trying to give a more complete answer :D


  • Ronald S

    I was trying to convert this:
    public System.Drawing.Image ResizeImage(System.Drawing.Image poImage, System.Drawing.Size poSize) {



    //Detach image from its source

    System.Drawing.Image oImageOriginal = (System.Drawing.Image)poImage.Clone();



    //Resize new image

    System.Drawing.Image oResizedImage = new System.Drawing.Bitmap(poSize.Width, poSize.Height, oImageOriginal.PixelFormat);

    System.Drawing.Graphics oGraphic = Graphics.FromImage(oResizedImage);

    oGraphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality ;

    oGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality ;

    oGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic ;

    Rectangle oRectangle = new Rectangle(0, 0, poSize.Width, poSize.Height);

    oGraphic.DrawImage(oImageOriginal, oRectangle);

    oGraphic.Dispose() ;

    oImageOriginal.Dispose();

    return oResizedImage;

    }

    form C to VB as my app is in VB and I can't find some of the relevent syntax to convert

    for example:
    public System.Drawing.Image ResizeImage(System.Drawing.Image poImage, System.Drawing.Size poSize)

    would convert to something like

    ResizeImage(poImage as
    System.Drawing.Image, poSize as System.Drawing.Size)

    etc:


    Thanks for your help

  • Sidon

    Just a few comments on the code.

    1) I would probably pass in the image as opposed to passing in the filename ..

    Dim poImage As Image = Image.FromFile(Image2Resize)

    You could then make an overload that took the filename and passed the image to the main function (just a bit more generic in the long run)

    2) Dim poImage As Image = Image.FromFile(Image2Resize)

    Its not too big of a deal here as you are disposing the object almost immediately after but I generally tell people to stay away from this method as it locks the file until disposed ... You can use a FileStream and Image.FromStream() to get around the locking.

    3) Based upon #2 you need to be very careful about being sure to dispose of the image (i.e. if an exception happenned in between the file lock would stay until the garbage collector picked up the image which is non-deterministic thus you can end up with "funny" bugs where it fails the first time then fails the next 20 succeeding the 21st for no apparent reason.

    Cheers,

    Greg


  • Resizing jpg to smaller resolution