کوچک نمایی تصاویر در Asp.NET با نسبت یکسان
در خیلی از سایت ها شاهد تصاویری هستیم که هیچ کدام اندازه واحدی ندارند ولی این باعث بهم ریختگی سایت نشده است دلیل آن این است که تمامی تصاویر با یک نسبت یکسان کوچک شده اند ، در حقیقت طول و عرض این تصاویر همگی از یک عدد معین کوچک تر هستند
در این مقاله روش کوچک نمایی عکس را به تناسب آموزش خواهم داد .
ابتدا یک ابع به نام image_resize بصورت زیر تعریف می کنیم ، این تابع با گرفتن پارامتر های مورد نیاز تصویر را کوچک می نماید :
Public Function img_resize(ByVal picname As String,ByVal maxHeight As Integer, ByVal maxWidth As Integer) As String
End Function
picname نام تصویری است که قصد کوچک سازی آن را داریم ( مثل ali132.jpg )
maxHeight حد اکثر طول تصویر و maxWidth حد اکثر عرض تصویر است (بر حسب پیکسل ).
ابتدا یک شی از نوع Image تعریف کرده و فایل عکس را به آن نسبت می دهیم (فرض کردم که تصویرم در پوشه mypics درون روت قرار دارد :
Dim currentImage As System.Drawing.Image = System.Drawing.Image.FromFile(server.mappath("mypics\") + picname)
این شی را برای بدست آوردن سایز اصلی تصویر نیاز داریم :
Dim imgHeight, imgWidth As Integer
imgHeight = currentImage.Height
imgWidth = currentImage.Width
کار اصلی ما اینجاست :
If imgWidth > maxWidth Or imgHeight > maxHeight Then
'Determine what dimension is off by more
Dim deltaWidth As Integer = imgWidth - maxWidth
Dim deltaHeight As Integer = imgHeight - maxHeight
Dim scaleFactor As Double
If deltaHeight > deltaWidth Then
'Scale by the height
scaleFactor = maxHeight / imgHeight
Else
'Scale by the Width
scaleFactor = maxWidth / imgWidth
End If
imgWidth *= scaleFactor
imgHeight *= scaleFactor
End If
در قطعه کد فوق ابتدا چک میشود که آیا سایز عکس ( چه طول چه عرض ) بزرگتر از ماکزیمم سایز تعیین شده هست یا خیر !
اگر جواب مثبت باشه :
1- یک متغیر به نام deltaWidth که تفاضل بین عرض عکس واقعی و ماکزیمم تعیین شده است تعریف می کنیم.
2- یک متغیر به نام deltaHeight که تفاضل بین طول عکس واقعی و ماکزیمم تعیین شده است تعریف می کنیم.
3- اگر تفاضل deltaHeight > deltaWidth بود
نسبت ماکسیسم طول را به طول واقعی عکس بدست می اوریم!
4- در غیر این صورت
نسبت ماکسیسم عرض را به عرض واقعی عکس بدست می اوریم!
5- این نسبت را به عنوان یک ضریب کوچک نمایی در نظر می گیریم ، وقتی این ضریب در طول و عرض عکس واقعی ضرب شود طول و عرض کوچک شده بدست می آید.
اکنون تگ img را با طول و عرض جدید شبیه سازی می کنیم :
Dim html As String
html = "<img src=""" + mydir + picname + """ height=""" & imgHeight & """ width=""" & imgWidth & ">"""
Return html
در نهایت تابع مورد نظر به صورت زیر خواهد بود :
Public Function img_resize(ByVal picname As String,ByVal maxHeight As Integer, ByVal maxWidth As Integer) As String
Dim currentImage As System.Drawing.Image = System.Drawing.Image.FromFile(server.mappath("mypics\") + picname)
Dim imgHeight, imgWidth As Integer
imgHeight = currentImage.Height
imgWidth = currentImage.Width
If imgWidth > maxWidth Or imgHeight > maxHeight Then
'Determine what dimension is off by more
Dim deltaWidth As Integer = imgWidth - maxWidth
Dim deltaHeight As Integer = imgHeight - maxHeight
Dim scaleFactor As Double
If deltaHeight > deltaWidth Then
'Scale by the height
scaleFactor = maxHeight / imgHeight
Else
'Scale by the Width
scaleFactor = maxWidth / imgWidth
End If
imgWidth *= scaleFactor
imgHeight *= scaleFactor
End If
Dim html As String
html = "<img src=""" + mydir + picname + """ height=""" & imgHeight & """ width=""" & imgWidth & ">"""
Return html
End Function
این ترفند سایز عکس را به نسبت یکسان کوچک می کند ولی حجمآن را تغییر نمیدهد !
برای اینکه بتوانیم حجم عکس را نیز کاهش بدهیم از متدی به نام thumbNail استفاده می کنیم .
برای این منظور یک صفحه به نام ShowThumbnail.aspx به پروژه اضافه کنید .
کد های زیر را در زیر روال رویداد لود شدن صفحه بنویسید :
Dim imageUrl As String = Request.QueryString("img")
Dim imageHeight As Integer = Request.QueryString("h")
Dim imageWidth As Integer = Request.QueryString("w")
If imageUrl.IndexOf("/") >= 0 Or imageUrl.IndexOf("\") >= 0 Then
'We found a / or \
Response.End()
End If
imageUrl = "mypics/" & imageUrl
Dim fullSizeImg As System.Drawing.Image
fullSizeImg = System.Drawing.Image.FromFile(Server.MapPath(imageUrl))
Response.ContentType = "image/jpg"
If imageHeight > 0 And imageWidth > 0 Then
Dim dummyCallBack As System.Drawing.Image.GetThumbnailImageAbort
dummyCallBack = New System.Drawing.Image.GetThumbnailImageAbort(AddressOf ThumbnailCallback)
Dim thumbNailImg As System.Drawing.Image
thumbNailImg = fullSizeImg.GetThumbnailImage(imageWidth, imageHeight, dummyCallBack, IntPtr.Zero)
fullSizeImg.Save(Response.OutputStream, ImageFormat.Gif)
Else
fullSizeImg.Save(Response.OutputStream, ImageFormat.Gif)
End If
از طریق querysting طول و عرض و اسم عکس به این صفحه پاس میشود .
کار اصلی به عهده متد GetThumbnailImage شی Image است که 4 تا پارامتر را دریافت و عکس بند انگشتی را بر میگرداند !
در نهایت هم این عکس بصورت OutputStream و مثلا در اینجا با فرمت Gif برگردانده میشود ( میتوانید فرمت را به دلخواه تغییر بدهید )
در ضمن برای استفاده از این متد تابع زیر را هم درون صفحه بگنجانید:
Function ThumbnailCallback() As Boolean
Return False
End Function
اکنون باید در تابع image_resize کمی تغییر بدهیم
بخش نهایی تابع که شبیه سازی تگ Img بود بصورت زیر تغیر داده میشه :
Dim html As String
If imgHeight <> currentImage.Height Or imgWidth <> currentImage.Width Then
html = "<a href=""" & IMAGE_DIRECTORY & Path.GetFileName(s) & """>" & _
"<img src=""ShowThumbnail.aspx?img=" & Path.GetFileName(s) & "&w=" & _
imgWidth & "&h=" & imgHeight & """ " & _
"height=""" & imgHeight & """ width=""" & imgWidth & """ border=1>" & _
"</a>"
Else
html = "<a href=""" & IMAGE_DIRECTORY & Path.GetFileName(s) & """>" & _
"<img src=""ShowThumbnail.aspx?img=" & Path.GetFileName(s) & """ " & _
"height=""" & imgHeight & """ width=""" & imgWidth & """ border=1>" & _
"</a>"
End If
Return html
توسط Thumbnail شما عکسی با حجم کمتر و به نسبت سایز تصویر جدید خواهید داشت
تابع جدید عکسی را بر میگرداند که علاوه بر کوچک نمایی به نسبت یکسان ، کاهش حجم به نسبت سایز تصویر داشته است .
البته نا گفته نماند که کیفیت در این روش دوم افت خواهد داشت.
از این تابع هرجایی میتوانید استفاده کنید : داخل کدهای html ، داخل یک دیتاگرید ، دیتالیست و ....
مثال :
<asp:GridView ID="GridView3" runat="server" AllowPaging="True" AllowSorting="True"AutoGenerateColumns="False" DataKeyNames="reply_pk" DataSourceID="reply_source"Width="100%" GridLines="None">
<Columns>
<asp:TemplateFieldSortExpression="reply_user">
<ItemTemplate>
<%#img_resize(Eval("my_img"),100, 80)%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
این یک گرید ویو است که پس از بایند توسط یک دیتاسورس عکس های مربوطه رو از ستون my_img خوانده و به نسبت کوچک و نمایش میدهد ، ماکزیمم طول برابر 100 و ماکزیمم عرض برابر 80 در نظر گرفته شده.
همچنین بنده یک کنترل جهت کوچک نمایی تصویر نوشته ام که نیازی به کد نویسی ندارد ، شما میتوانید این کنترل را از اینجا دانلود نمایید .