تغییر سایز داینامیک تصاویر در ASP.NET MVC

یکشنبه 20 فروردین 1396

شاید شما هم تا حالا برای تغییر سایز تصاویر سایتتون اول آنها را تغییر سایز می دادید بعد داخل پوشه تصاویر بند انگشتی دخیره می کردید، ما در این مقاله روشی را به شما آموزش میدهیم که بدون نیاز به ذخیره تصاویر بند انگشتی در هاست، در زمان درخواست کاربر تصاویر به صورت داینامیک تغییر سایز پیدا کرده و به کاربر برگشت داده شود.

تغییر سایز داینامیک تصاویر در ASP.NET MVC

امروز قصد داریم یک راه سریع برای تغییر سایز تصاویر در ASP.NET MVC  به شما آموزش دهیم .

بعد از طراحی سایت بهتر است که معیارهای کارایی سایت خود را بسنجید تا ببینید سرعت سایت شما در چه حدی است. شما می توانید از طریق سایت gtmetrix.com میزان سرعت سایت خودتتان را تست کنید.

مثلا وقتی یکی از سایت ها را تست کردیم متوجه شدیم که 6 تصویر از تصاویر وبلاگ حجم زیادی را اشغال کردند و با حذف آن تصاویر رتبه سایت  از نظر سرعت به B ارتقا پیدا کرد.( از  Fکه بهتر بود!)

مشکل این بود که تصاویر  640x480 را برای نوشته های وبلاگ آپلود کرده بودیم و یک ناحیه تعریف کرده بودیم که تصاویر را داخل یک   DIV می انداختیم و به container/Bootstrap اجازه داده بودیم که ریسپانسیو بودن آن را بررسی و مدیریت کند.

درواقع مشکل تعداد بایت های انتقالی به مرورگر در هربار انتقال بود. شما باید قبل از انتقال تصاویر به مرورگر آنها را در ابعاد صحیح کوچک کنید و این راه باعث می شود شما با ارسال تعداد بایت های کمتر به مرورگر کارایی سایت را افزایش دهید و کاربرانتان را خوشحال کنید.

 شما می توانید از یکی از دو راه زیر این کار را انجام دهید :

1-از دستوری استفاده کنید که تمام تصاویررا قبل از آپلود تغییر سایز داده و در پوشه تصاویر بند انگشتی(thumbnail) ذخیره کند.

2-در هنگام درخواست کاربر به صورت اتوماتیک تصاویر را کوچک کنید.

از آنجا که ما نمی خواهیم حجم زیادی از فضای هاست خود را به ذخیره تصاویر اختصاص دهیم راه دوم را انتخاب می کنیم .

در خواست تصویر هم یک در خواست محسوب می شود. با استفاده از یک سری کنترلر ها شما می توانید  یک عکس را کمرنگ تر کنید.

در تگ تصویر(image tag) ما به یک اکشن در کنترلر اشاره می کنیم(Url.Action) که کار تغییر سایز را برای ما انجام می دهد و نتیجه را برمی گرداند.

همه ی چیزی که ما به آن نیاز داریم نام فایل در قسمت  ImageResult داخل ActionResult است.

ابتدا از اکشن کنترلر شروع می کنیم:

 public ActionResult Thumbnail(string filename)
        {
            var img = new WebImage(filename)
                .Resize(291, 285, false, true);
            return new ImageResult(new MemoryStream(img.GetBytes()), "binary/octet-stream");
        }

ما فقط در صفحه اصلی نیاز داریم که تصاویر را تغییر سایز دهیم پس دستورات را داخل  Home controller  می نویسیم ، شما می توانید یک سرویس کنترلر ایجاد کنید و دستورات را داخل آن قرار دهید و در قسمت های مختلف از آن استفاده کنید.

ما همچنین به ابعاد تصاویردر تگ تصویر نیاز داریم که فعلا آن را در این قسمت قرار می دهیم و بعد آن را ویرایش می کنیم .(داخل فایل css قرار می دهیم.)

لطفا به کلاس WebHelper  که  WebImage هم نامیده می شود توجه داشته باشید و آن را به پروژه خود اضافه کنید.

این WebHelper  امکان دستکاری تصاویر به صورت داینامیک را فراهم می کند، ما فقط از امکان تغییر سایز این کلاس استفاده می کنیم در صورتیکه این کلاس  توانایی های دیگری هم دارد:

1-امکان افزودن عکس یا نوشته ی واتر مارک به تصاویر

2-امکان کلون کردن (clone)

3-امکان برش تصاویر(crop)

4-چرخش عمودی و افقی

5-چرخش به چپ و راست

این کلاس از متد ساده ای استفاده کرده و شما می توانید به راحتی قبل از برگرداندن تصویر آن را بچرخانید یا واتر مارک به آن اضافه کنید.

ImageResult ActionResult

ImageResult  یک ActionResult ساده هست که یک جریان باینری هشتایی (binary/octet-stream)بر می گرداند.

public class ImageResult : ActionResult
{
    public ImageResult(Stream imageStream, string contentType)
    {
        if (imageStream == null)
            throw new ArgumentNullException("imageStream");
        if (contentType == null)
            throw new ArgumentNullException("contentType");

        this.ImageStream = imageStream;
        this.ContentType = contentType;
    }

    public Stream ImageStream { get; set; }
    public string ContentType { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        var response = context.HttpContext.Response;

        response.ContentType = this.ContentType;

        byte[] buffer = new byte[4096];
        while (true)
        {
            int read = this.ImageStream.Read(buffer, 0, buffer.Length);
            if (read == 0)
                break;

            response.OutputStream.Write(buffer, 0, read);
        }

        response.End();
    }
}

برای بهینه سازی کارایی سایت بهترین راه استفاده از جریانی از بایت ها برای انتقال است. کاربران تصاویر را در حافظه خودشان ذخیره می کنند و بعد آن را حذف می کنند پس استفاده از این جریان سریعترین راه برای انتقال  تصاویر به دست کاربران است.

سینتکس های Razor چگونه عمل می کنند؟

سینتکس های Razor ممکن است یک مقدار عجیب به نظر برسند اما این یک راه سریع و موذیانه برای برگرداندن تصاویراست. 

<img src="@Url.Action("Thumbnail", "Home", new {FileName="~/Content/Images/1.jpg"})"
     class="img-responsive"
     title="@post.Title"
     alt="@post.Title" width="291" height="285" />

ساده است درسته؟

این خیلی خوب است که ما مجبور نیستیم ابعاد یک تصویر را برای مرورگر تعیین  کنیم .با استفاده از این راه ابتدا ناحیه تصویر مشخص می شود و در آن قسمت جریانی از بایت ها در تصویر پر می شود.

اگر ابعاد تصاویر را تعیین نکنیم مرورگر منتظر می ماند تا تصویر به صورت کامل دانلود شود و در بارگذاری صفحه تاخیر ایجاد می شود.

آیا ما می توانیم آن را سریعتر از این هم  بارگذاری کنیم؟

یک مقدار بیشتر فکر کنید می توانید بارگذاری تصاویر را سریعتر کنید تا کارایی سایت از این هم بیشتر شود.

ما می توانیم قبل از کنترلر اکشن ActionFilters را اضافه کنیم تا اکشن را به راحتی کش(cache) کنیم .

[ETag, OutputCache(Duration = 3600, VaryByParam = "filename")]
public ActionResult Thumbnail(string filename)
{
    var img = new WebImage(filename)
        .Resize(291, 285, false, true);
    return new ImageResult(new MemoryStream(img.GetBytes()), "binary/octet-stream");
}

خروجی کش برای 1 ساعت باقی می ماند و ما می توانیم با نام فایل آن را کش کنیم .

Etagیک فیلتراکشن هست که برای تعیین اجبار بروزرسانی یا عدم بروزرسانی فراخوانی می شود .

آیا این روش واقعا تاثیر دارد؟

بعد از اعمال همه ی این تغییرات ما دوباره وارد سایت GTMetrix.com شدیم و یک تست مجدد گرفتیم

رتبه ما به A تغییر پیدا کرده بود، همه ی نتایج ما سبز بود ، زمان لود سایت کاهش پیدا کرده بود ولی میزان درخواست ها یک مقدار افزایش داشت.

این نکته هم جالب است که اگر سایت شما بیش از 3 ثانیه بارگذاری شود 40% از کاربران خود را از دست می دهید.

نتیجه گیری:

ما امروز یک راه برای ویرایش تصاویر درحد مناسب سایت با استفاده از ImageResult  و کلاس WebImage به شما آموزش دادیم.

شما باید همیشه سایت خود را برای کارایی حداکثری بهینه کنید، شما می توانید کد های خود را نیز فشرده کنید، تصاویر فقط یک جنبه برای بهینه سازی سایت شماست. در آینده ما راه های دیگر بهینه سازی سایت های  ASP.NET MVC را نیز به شما آموزش می دهیم . شما می توانید سوال های خود را در مورد افزایش کارایی سایت از طریق انجمن سایت با ما درمیان بگذارید.

آموزش asp.net mvc

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید