Asp.Net ile Dinamik Resim Küçültme ve Sıkıştırma

asp.net logoMerhaba arkadaşlar, bu makalede asp.net ile dinamik olarak resim küçültme göstereceğim. öncelikle dinamik olarak resim kırpmak nedir bunu açıklayalım..Net ile halihazırda bir resim dosyasını istenen ebatlarda küçültüp kaydetmeyi biliyoruz fakat bu işlem ya resim dosyasını gerçekten etkileyecek ya da kopyalayıp başka bir yere kaydedecektir dolayısıyla işin içinde fiziksel bir dosya işlemi olduğu için performans kaybı yaşanacaktır. Zaten bizim asıl istediğimiz şey varolan büyük bir resmi kullanıcıya o anki sayfa talebi için küçük göstermektir bunun için gerçekten dosyayı küçültüp kaydetmeye gerek yoktur.

Bunu istemememizin ise bir kaç sebebi olabilir; örneğin yüksek kalitede ve çok yer kaplayan resimlerinizi performans artırma amacı ile orjinal halini bozmadan sıkıştırabilir ve kullanıcılara böyle göstermek isteyebilirsiniz. nitekim google page insight aracını kullanarak sitenizin hızını test ettiğinizde google size sitenizi yavaşlatan en büyük etkenlerden birinin resim dosyalarınız olduğunu söyleyecektir fakat sizde benim gibi birazdan göstereceğim yöntem ile resim dosyalarını dinamik olarak sıkıştırdığınızda farkı büyük oranda hissedeceksiniz.

Şimdi yavaş yavaş senaryomuzu açıklayalım. Normal de aşağıdaki gibi bir html img etiketi src özelliği ile belirtilen adresden direkt bir resim dosyasını çeker ve sayfada gösterir. siz eğer src olarak resim dışında bir dosya belirtirseniz hata alırsınız çünkü http header kısmındaki content type özelliği bir resim dosyayı belirtmiyor olacaktır.

<img src=”/images/logo.png”/>

Bizim burada yapacağımız ise img elementine gerçek bir resim dosyası yerine dinamik olarak resim döndüren bir web sayfasını kaynak olarak döndürmek. yani img elementi verdiğimiz adrese bir istek gönderecek ve geriye bir resim dosyası bekleyecektir. bizim web sayfamız ise gelen talepteki dosya yolunu (ki biz bu yolu querystring olarak göndereceğiz) alacak ve sıkıştırma yani küçültme işlemini yapacak ve geriye html olarak değil de resim dosyası cinsinden veri döndürecektir. bu şekilde çalışma zamanında resmi küçültmüş ve göstermiş olacağız. şimdi resmikucult.aspx isimli web sayfamızı oluşturalım

string url = Request.QueryString("resimyolu");
WebClient webClient = new WebClient();
byte[] data = webClient.DownloadData("http://localhost:45897/" + url);
MemoryStream ms = new MemoryStream(data);
System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
double oran = returnImage.Width / returnImage.Height;
returnImage = Resize(returnImage, 150, 150 / oran);
Response.ContentType = "image/jpeg";
returnImage.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);

yukarıda WebClient sınıfının DownloadData özelliği ile verilen url’deki veriyi byte olarak bir dğeişkene aktarıyoruz. Ardından MemoryStream ile System.Drawing.Image.FromStream methodunu kullanarak byte cinsinden veriyi image tipine çeviriyoruz. küçültme oranımızı hesaplayıp oran değişkenine aktarıyoruz. Response.ContentType değişkeni ile sayfanın ne tür bir cevap döndüreceğini belirtiyoruz örneğimizde jpeg yani resim uzantılı bir veri döndüreceğini söyledik. returnImage değişkenimiz image sınıfından türediği için Save metodu ile içeriğini ister sunucu üzerinde ister isek de bir stream içine yazabiliriz bir burada response.OutputStream ile sayfanın cevap olarak vereceği verinin içeriğine resim dosyamızı yazdık ve resim olarak çıktı ürettik.

Şimdi resmikucult.aspx sayfamızın resmi küçültmek için kullandığı algoritmayı yazalım. normalde bu işi algoritma kullanmadan hazır .net fonksiyonu ile de yazabilirsiniz. örnek şöyle

Image kucukresim = returnImage.GetThumbnailImage(150, 150, null, System.IntPtr.Zero);

yukarıdaki fonksiyon ile belirtilen genişlik ve yükseklikte bir küçük resim elde ediyoruz. bunu da image türünden bir değişkene aktarıyoruz. fakat tercih olarak kendiniz de bir algoritma kullanabilirsiniz örnek olarak benim internette bulduğum hazır bir algoritma şöyle

public static System.Drawing.Image Resize(System.Drawing.Image imgToResize, int h, int w)
{
	Size size = new Size(w, h);
	int sourceWidth = imgToResize.Width;
	int sourceHeight = imgToResize.Height;

	float nPercent = 0;
	float nPercentW = 0;
	float nPercentH = 0;

	nPercentW = (Convert.ToSingle(size.Width) / Convert.ToSingle(sourceWidth));
	nPercentH = (Convert.ToSingle(size.Height) / Convert.ToSingle(sourceHeight));

	if (nPercentH < nPercentW) {
		nPercent = nPercentH;
	} else {
		nPercent = nPercentW;
	}

	int destWidth = Convert.ToInt32(sourceWidth * nPercent);
	int destHeight = Convert.ToInt32(sourceHeight * nPercent);

	Bitmap b = new Bitmap(destWidth, destHeight);
	Graphics g = Graphics.FromImage((System.Drawing.Image)b);
	g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

	g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
	g.Dispose();
	return (System.Drawing.Image)b;
}

Kullanımı için ie şöyle bir kod parçası yazabilirsiniz.

Image kucukresim = Resize(returnImage, 150, 150 / oran);

burada resmin en boy oranını korumak için genişliğini sabit veriyoruz fakat yüksekliğini genişlik ile belirlenen oran’ın bölümü olarak veriyoruz. ve fonksiyonumuz bize resim küçük resim döndürüyor.

Sayfamızı hazırladık. şimdi bu sayfaya nasıl istekte bulunacağımızı görelim. herhangi bir html dosyasında ya da web formda img etiketine şöyle bir ifade yazarsanız dinamik olarak küçültülmüş bir resim elde edersiniz

<img src="/resimkucult.aspx?resimyolu=%2F/images/%2Flogo"/>

Bu şekilde sayfanızdan resmi talep edebilirsiniz. fakat resmin uzantısını yazarsanız verdiğiniz linki gerçek bir dosya olarak algılayıp bulamayınca hata verecektir. dosya uzantısını kendiniz string olarak ekleyebilirsiniz. ayrıca uzantısı ne olursa olsun geri dönen değer sizin response.contenttype property’sinde belirttiğiniz değer olacaktır. bunu engellemek için dosya uzantısını da parametre olarak gönderebilirsiniz.

 

       

 

Umarım faydalı olmuştur. İyi çalışmalar…

Mustafa Tayyip YETİŞ
Yazılım Geliştirme Uzmanı

0.0 Ort. (0% puan) - 0 oy

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir