Kép átméretezése arányosan, szépen

Képek átméretezéséhez lehet használni az Image.GetThumbnailImage metódust, aminek az egyik baja, hogy nem túl szép az átméretezett eredmény, a másik, hogy vadul képes ExternalExceptionöket és OutOfMemoryExceptionöket dobálni, ha nem tetszik neki az eredeti kép. Van más lehetőség is.

Használhatjuk például a Graphics.DrawImage metódust, ráadásul a Graphics objektumnak még az InterpolationMode tulajdonságát is be tudjuk állítani:

  private static Image ResizeImage( Image originalImage, int maxWidth, int maxHeight )
  {
    if( originalImage.Width == maxWidth && originalImage.Height == maxHeight )
    {
        return originalImage;
    }

    float ratio;
    float ratioWidth;
    float ratioHeight;

    ratioWidth = (float) maxWidth / (float) originalImage.Width;
    ratioHeight = (float) maxHeight / (float) originalImage.Height;
    ratio = ratioHeight < ratioWidth ? ratioHeight : ratioWidth;

    int destWidth = (int) ( originalImage.Width * ratio );
    int destHeight = (int) ( originalImage.Height * ratio );

    Bitmap bitmap = new Bitmap( destWidth, destHeight );
    using( Graphics g = Graphics.FromImage( (Image) bitmap ) )
    {
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        g.DrawImage( originalImage, 0, 0, destWidth, destHeight );

        return (Image) bitmap;                
    }
  }

Ha a bemenetünk stream, akkor abból az Image.FromStream metódussal lehet Image objektumot készíteni. Ha byte[], akkor még egy MemorySteam is kell és persze minden IDisposable:

    using( MemoryStream originalStream = new MemoryStream( originalContent ) )
    {
        using( Image originalImage = Image.FromStream( originalStream ) )
        {
            using( Image resizedImage = ResizeImage( originalImage, MaxWidth, MaxHeight ) )
            {
                using( MemoryStream resizedStream = new MemoryStream() )
                {
                    resizedImage.Save( resizedStream, ImageFormat.Jpeg );
                    byte[] resizedContent = resizedStream.ToArray();
                }
            }
        }
    }

Tapasztalatom szerint a 100 pixel környékére kicsinyített fényképeknél a JPEG és a PNG hasonló minőséget produkál, miközben a JPEG fájl lényegesen kisebb, nem ritkán tízszeres különbség is van.

One thought on “Kép átméretezése arányosan, szépen

  1. László

    Apró kiegészítés: a resizedImage.Save kaphat egy harmadik paramétert is (EncoderParameters), ahol pl. egy Encoder segítségével szabályozni tudjuk az átméretezett kép minőségét is.

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s