Bir Resmi Dinamik Olarak Url Parametreleri İle Resize Etme

Selamlar,

Bugün kaynağı verilen bir resmin istenen boyutlarını, Url’de belirleyip, memory’de resize edeceğiz. Buna Dynamically Resize Image On-The-Fly deniyor. Yani ilgili image’i herhangi bir fiziksel alana yazmadan, yeninden boyutlandırıyoruz.

image_9

Image Source: https://www.hanselman.com/blog/content/binary/Windows-Live-Writer/fcafa28f54d3_C700/image_9.png

Öncelikle ilgili static file’a browserda erişilmeye çalışıldığı zaman, ilgili Action’a gidilebilmesi için “CustomRouteHandler” tanımlanması gerekmektedir. Ayrıca Routing için de başdaki default “images” keyword’ünün ardından “{*ImageName}” şeklinde istenen uzunlukta text’in yazılabileceği alan tanımlanmıştır.

RouteConfig:

Şimdi sıra geldi custom olarak tanımlanan “CustomPNGRouteHandler” ‘ın oluşturmaya. Yukarıdaki resimde de görüldüğü gibi, çalışma adımlarında “IHttpHandler” “Page,Controller ve HttpHandler”‘ın hepsini kapsamakta ve tüm adımların temelini oluşturmaktadır. Yani tüm requestler “IHttpHandler“‘dan geçer. Bunu sakın unutmayın. “IRouteHandler” interfaceinden türetilen ilgili “CustomPNGRouteHandler” class’ı aşağıdaki gibi oluşturulur. Ayrıca daha en başta ilgili route’a gelindiği zaman, bir takım işlem adımlarına ait istenen kodun yazılabilmesi için “IHttpHandler”‘dan türetilmiş “CustomPNGHandler” sınıfı oluşturulmuştur.

CustomPNGRouteHandler:

CustomPNGHandler:  İşte bütün bussines’ın döndüğü yer burasıdır. Şimdi adım adım neler olur inceleyelim:

  1. Kısım SEO amaçlı resimin önüne konmuş olan bir Url Title’ın olup olmadığına bakılır. Var ise temizlenip, ham image ismi uzantısı ile “RealFileName” değişkenine atanır. Örnek: http://localhost:11590/images/cdn/seo-amacli-deneme-resmi-bear.jpg?w=600&h=400 . Yandaki koyu renkli text kaldırılıp, sadece resmin adı alınır. Ayrıca “imagePath“‘e resmin yolu atanır.
  2. Kısım Image’in gerçekten var olup olmadığına bakılır. Eğer yok ise defualt belirlenen bir resim atanır. Ayrıca eğer resmin adının başında herhangi bir SEO tanımlaması yoksa yine resmin var olup olmadığı durumlarına da burada bakılır.
  3. Kısım Bu bölümde “?w=600&h=300” gibi image’in resize edilmesi istenen boyutları url’den pars edilir: İlgili url 2 farklı yolla pars edilmiştir. 1. yöntemde Linq ve Regex kullanılmıştır. 2. yöntem de ise “char.IsDigit()” methodu ile sayısal alanlar alınmıştır. İlgili resize işlemi için gerekli “width ve height” değerlerinin alımında, 3 farklı durum söz konusudur:
    • 1. durum “width” ve “height“2 değerin de alınması ve “ResizeImage()” methodunun çağrılması.
    • 2. durum “width” ve “height” değerlerinden sadece 1 değerin gelmesi ve gelen değerin “0”‘dan büyük olması durumudur. Bu durumda “width ve height” değerlerinden hangisinin geldiğine bakılıp, gelmeyen değere “0” atanır ve “ResizeImage()” methodu çağrılır.
    • 3. durumda herhangi bir resize değeri gönderilmediği için, resmin orjinal boyutları ile ekrana basılır.

ResizeImage: İlgili image’in url’de belirlenen boyutlara göre boyutlandırıldığı yer burasıdır. Burda da 3 durum söz konusudur:

  1. Durum : En başta ilgili image’in Aspect Ratio’su “dblRatio” değişkenin atanır. Eğer gelen image boyutlarından birisi “0” ise bu değer, ilgili image’in bulunan Aspect Ratio oranı ile bilinen boyutuna göre hesaplanır.
  2. Eğer image’in resize amaçlı belirtilen boyutlarından biri “width veya height” image’in gerçek boyutundan büyük ise, kala alınmaz ve işleme image’in orjinal boyutuna göre devam edilir.
  3. Eğer belirtilen yeni boyutlar image’in yeni aspect ratio’suna uymuyor ise, büyük olan boyut sabit alınarak, diğer boyut aspect ratio oranına göre hesaplanır ve resize işlemi bu yeni boyutlara göre yapılıp oluşturulan yeni “Bitmap” geriye döndürülür.

Web.config: Tüm static filelara erişim yetkisi “runAllManagedModulesForAllRequests=true” değeri atanarak verilir. Yani *.* PNGs, PDFs, gibi tüm filelar da ASP.NET’in full pipe line’ına katılır. Eğer bu işlemi IIS tarafında halledilir ise çok daha performanslı bir iş yapmış olunur. Aşırı yük testi yapılarak sayfanın takip edilebilmesi için “ApplicationInsightsWebTracking” projeye eklenmiştir.

Geldik bir makalenin daha sonuna. Bu makalede static bir resmin, yerine göre nasıl farklı boyutlarda Aspect Ratio oranı bozulmadan Resize edilebileceğini ve static bir dosyaya Mvc Custom Routing ile nasıl erişilebileceğini hep beraber inceledik. Bu makalenin işinize yaramasını temenni eder, şimdiden başarılar dilerim.

Yeni bir makalede görüşmek üzere hepinize hoşçakalın.

Source Code: https://github.com/borakasmer/OnMemoryResizeImage

Kaynaklar : Scott Hanselman Blog, Msdn Magazine

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

14 Cevaplar

  1. Fatih dedi ki:

    Paylaşımınız için teşekkürler Bora bey. Aynı işlemi yapan hazır bir bileşen de mevcut.
    http://imageresizing.net/

    • borsoft dedi ki:

      Teşekkürler Fatih,
      Imagelerin başına SEO amaçlı url text desteği veren bir servis şu anda yok.

      • Fatih dedi ki:

        resmin adını bu-benim-resmim.jpg olarak kaydedersek ve uygulamada src=”bu-benim-resmim.jpg?w=100″ olarak kullanırsak olur sankimsi

        • borsoft dedi ki:

          Selam Ferih,

          İşte burada amaç resmin adını o şekilde değiştirmemek. Bu makalede anlattığım örnekde, resmin önüne “-” istenen herşey yazılabiliyor. Mesela haber title. Hem de resmin adından bağımsız :) Bu gerçekten önemli bir konu. Tüm resimlerin ismini haber title yapamazsınız. Hatta yapmamalısınız. Haberin başlığını değişince resmin adınıda mi değiştiriceğiz :) Seo amaçlı resim adları kısaca önemli.

          İyi çalışmalar.

  2. Ferih dedi ki:

    kolay gelsin yazı için elinize sağlık benim konuyla alakasız bir sorum olacaktı sizin tecrübelerinize göre kolay bir soru olabilir kusura bakmayın haber sitelerinde veya blog sitelerinde kullanılan text editorlerde kullanılan alana script yazarak bir açık oluşabiliyor bu açığı nasıl kapatılıyor teşekkürler

    • borsoft dedi ki:

      Selam Ferih,

      Aslında birçok yolu var. Mesela şu şekilde ‘@RenderSection(“body_scripts”, false)’önlem alabilirsin.

  3. sedat dedi ki:

    ‘DynamicPNGs’ dosyasını veya bütünleştirilmiş kodunu ya da bağımlılıklarından birini yükleyemedi. Sistem belirtilen dosyayı bulamıyor.

  4. sedat dedi ki:

    DynamicPNGs yerine namespace ismini yazıp hallettim fakat bu sefer de şöyle bir sorun var. Login olurken bilgileri [HttpPost] attributene sahip login action ını çağırdığımda CustomPNGRouteHandler:IRouteHandler class içersindeki GetHttpHandler fonksiyonu tetikleniyor. CustomPNGRouteHandler class ı içersinde GetHttpHandler fonksiyonunda ImageName değeri null geliyorsa CustomPNGHandler classını kullanmadan sistemin rutin şekilde çalışmasını istiyorum. Araştırdığımda context.Response.Redirect(“http://www.siteadi.com”, true); şeklinde bir çözüm var fakat o request içersinde benim kullanıcı adı ve şifre bilgilerim de mevcut

  5. sedat dedi ki:

    Kısacası kullanıcı adı ve şifre bilgilerini girip submit ile post ettiğimde => http://localhost:51131/images?action=login&controller=panel göyle bir ur tetikleniyor. GetHttpHandler içersinde return new DefaultHttpHandler() da denedim yine olmadı. Konu ile ilgili çözümü bir yandan da araştırıyorum. Eğer daha iyi ve kolay bir yolu varsa açıklayabilirseniz sevinirim

  6. cihan dedi ki:

    Bora kardeşim selam, öncelikle eline sağlık çok güzel bir modül olmuş ve kullanıyorum. Yalnız küçük resimlerin görsel kalitesini biraz daha yüksek gösterme şansımız yani böyle bir parametre ekleme imkanımız var mı?

    • borsoft dedi ki:

      Selam Cihan,

      Var olan malzeme belli. Bir resmi var olan çözünürlüğünden daya yüksek çözünürlükte ve en az aynı kalitede göstermek için onu yeniden işlemelisin. Yani o artık aynı resim değildir. Bunun için özel gelişmiş resim uygulamarı var. Resmi yeniden pixel pixel render edip oluşturuyor. Uzun lafın kısası var olan çözünürlükten daha küçük çözünürlüklere çevirebilir ama daha yüksek çözünürlüklere getirmek için gelişmiş bir program yazmalısın. Parametre ile çözülebilecek bir durum yok.

      İyi çalışmalar.

      • cihan dedi ki:

        Bora selam tekrar, ben o anlamda dememiştim aslında. 1500×1500 bir imajı w=300 diye çağırınca oluşan kötü bir görüntü olabiliyor bu yüzden işleme kalitesini artıracak bir parametre nereye eklenebilir senin kodunda diye sormuştum aslında. HighQualityBicubic gibi bir parametre var aslında ama yine de bozabiliyor. Sonrasında ben onu cevabın mail olarak gelecek diye düşündüğüm için görmedim ve saçma da olsa şu şekilde bir yöntem bularak hallettim kendimce. <img width=300 kullanıyorsam için <img src="xx.jpg" olarak çektiğim imaja ?w=500 değeri verdim böylece daha kaliteli imaj çekmiş oldum. Biraz kulağı tersten tutmak gibi oldu ama işe yaradı. Teşekkürler :)

      • cihan dedi ki:

        Bir de her seferinde tekrar yüklüyordu resimleri, ben ProcessRequest 3.kısımda context.Response.ContentType satırının altına aşağıdaki 2 satırı ekleyip en azından client tarafında cache’lenmesini sağladım.
        context.Response.Cache.SetCacheability(HttpCacheability.Public);
        context.Response.Cache.SetMaxAge(TimeSpan.FromDays(1));

        Sorum ise bu yaratılan imajları herkes için yaratılmadan sunucu tarafında cachelenmesi nasıl sağlanabilir birkaç şey denedim ama uyum sağlamadı. 1-2 satır ekleyerek bunu sağlamanın kolay bir yolu var mı yoksa uzun uzun sunucuda bir cache klasör oluşturup oraya kaydetmesini sağlayıp ara ara burayı kontrol edip yenileyecek bir sistem mi kurmak gerekir?

        Yardımcı olabilirsen sevinirim, teşekkürler.
        Cihan

cihan için bir cevap yazın Cevabı iptal et

E-posta hesabınız yayımlanmayacak.