Generovanie thumbnailov a zmena veľkosti obrázka - clipp a scale.

Ako vytvoriť Thumbnail z uploadnutého obrázku, opať veľmi bežne sa vyskytujúca téma na blogoch. Často však potrebujeme rozhodovať o tom, ako sa má obrázok, ktorý nevyhovuje predpísaným rozmerom spracovať, či a ako sa má orezať, či ho necháme zmenšiť neproporčne atd. Ponúkam kúsok kódu, ktorý zvláda všetky tieto bežné situácie a ak niekto chce používateľovi ešte umožniť rozhodnúť o umietnení clipovacieho okna, poľahky si to do metódky dorobíte.

Módy zmeny veľkosti obrázka:

  • Clipp - Obrázok zostáva proporčne nezmenený, môže prísť ku jeho zmenšeniu. V prípade, že v jednom rozmere prekračuje vymedzenú cieľovú veľkosť, je orezaný buď z dola, alebo z prava. To je priestor pre ďalšie parametre pre orezenie.(presná pozícia,prípadne aspoň možnosť voľby orezania vertikálne a horizontálne z prava, z ľava, na stred resp. z hora, z dola, na stred
  • ScaleToFit - Obrázok zmení veľkosť presne podľa cieľových rozmerov, môže prísť ku deformovaniu proporcií obrázka
  • ScaleIntoBounds - Obrázok zostáva proporčne nezmenený, cieľové rozmery slúžia ako vonkanjšie hranice, do ktorých sa snaží obrázok vtesnať

public enum ScaleType

    {

        Clipp,

        ScaleToFit,

        ScaleIntoBounds

    }

 

    public class ImageHelper

    {

        public static Bitmap GetThumbNail(Bitmap oImg, Size oTmbSize, ScaleType eScaleType)

        {

            int iSourceWidth = oImg.Width;

            int iSourceHeight = oImg.Height;

            if (eScaleType == ScaleType.Clipp || eScaleType == ScaleType.ScaleIntoBounds)

            {

                SizeF oTmbSizeF = (SizeF)oTmbSize;

                SizeF oOrigSizeF = (SizeF)oImg.Size;

 

                float fWidthRatio = oOrigSizeF.Width / oTmbSizeF.Width;

                float fHeightRatio = oOrigSizeF.Height / oTmbSizeF.Height;

 

                if (eScaleType == ScaleType.Clipp)

                {

                    if (fWidthRatio < fHeightRatio)

                        iSourceHeight = (int)Math.Round((double)(oTmbSizeF.Height * fWidthRatio));

                    else

                        iSourceWidth = (int)Math.Round((double)(oTmbSizeF.Width * fHeightRatio));

                }

                else

                {

                    if (fWidthRatio > fHeightRatio)

                        oTmbSize.Height = (int)Math.Round((double)(oOrigSizeF.Height / fWidthRatio));

                    else

                        oTmbSize.Width = (int)Math.Round((double)(oOrigSizeF.Width / fHeightRatio));

                }

            }

 

            Bitmap oThumbNail = new Bitmap(oTmbSize.Width, oTmbSize.Height, PixelFormat.Format24bppRgb);

 

            using (Graphics oGraphics = Graphics.FromImage(oThumbNail))

            {

                oGraphics.CompositingQuality = CompositingQuality.HighQuality;

                oGraphics.SmoothingMode = SmoothingMode.HighQuality;

                oGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

 

                Rectangle oDestRectangle = new Rectangle(0, 0, oTmbSize.Width, oTmbSize.Height);

                Rectangle oSrcRectangle = new Rectangle(0, 0, iSourceWidth, iSourceHeight);

 

                oGraphics.DrawImage(oImg, oDestRectangle, oSrcRectangle, GraphicsUnit.Pixel);

            }

            return oThumbNail;

        }

 

        public static void SaveCompressedJpg(Image oImg, string sFileName, short shCompressLevel)

        {

            using (EncoderParameters oCodecParams = new EncoderParameters(1))

            {

                using (EncoderParameter oParam = new EncoderParameter(Encoder.Quality, (long)shCompressLevel))

                {

                    oCodecParams.Param[0] = oParam;

                    ImageCodecInfo oCodecInfo = FindEncoder(ImageFormat.Jpeg);

                    oImg.Save(sFileName, oCodecInfo, oCodecParams);

                }

            }

        }

 

        private static ImageCodecInfo FindEncoder(ImageFormat eImgFormat)

        {

            ImageCodecInfo[] arrCodecInfo = ImageCodecInfo.GetImageEncoders();

            ImageCodecInfo[] arrCodecInfo2 = arrCodecInfo;

            for (int i = 0; i < arrCodecInfo2.Length; i++)

            {

                ImageCodecInfo oCodecInfo = arrCodecInfo2Idea;

                if (oCodecInfo.FormatID.Equals(eImgFormat.Guid))

                    return oCodecInfo;

            }

            return null;

        }

 

}

Ako to použiť? Po úspešnom uložení napr. článku alebo update, môžeme spracovať obrázok. Nemusíme to vnárať do tranzakcie, ak je obrázok nepovinný, len upozorniť používateľa, že obrázok sa nepodarilo spracovať.

try

        {

            if (!Directory.Exists(destPath))

                Directory.CreateDirectory(destPath);

 

            if (FUPict.HasFile)

            {

                using (Bitmap oImage = (Bitmap)Bitmap.FromStream(FUPict.FileContent))

                {

                    FUPict.FileContent.Position = 0;

                    //cieľovú veľkosť môžeme urobiť configurovateľnú, napr. cez custom configuračnú sekciu vo webconfigu, potom ale odporúčam odkladať aj pôvodný obrázok

                    //ak si to vzhľadom na zdroje servera môžeme dovoliť kôly resizeu pri zmene veľkosti, ale na to treba napísať navyše nejaký jednodcuhý patcher

                    using (Bitmap oThumbImg = ImageHelper.GetThumbNail(

                        oImage,

                        new Size(100, 100),

                        ScaleType.Clipp))

                    {

                        //podobne ako veľkosť môžeme urobiť configurovateľný aj cieľový formát obrázka

                        ImageFormat oImgFormat = ImageFormat.Jpeg;

                        //odporúčam vytvárať subfoldre za predpokladu, že bude existovať rádovo väčši počet obrázkov ako 1000 napr. podľa dátumu

                        string sFullPath = Server.MapPath(destPath + "\\test.jpg");

 

                        if (oImgFormat == ImageFormat.Jpeg)

                            //kvalitu odporúčam opať urobiť konfigurovateľnú

                            ImageHelper.SaveCompressedJpg(oThumbImg, sFullPath, 60);

                        else

                            oThumbImg.Save(sFullPath, oImgFormat);

                    }

                }

            }

        }

        catch (Exception oEx)

        {

            //Display warning

            CtrlStatus.AddMsg(Resources.ErrorMessages.SavingImageFailure);

            //Log Error

        }

Komentáre

Bez komentárov

Prihlásiť | Registrovať | Pomoc