簡體   English   中英

asp.net版本的timthumb php類

[英]asp.net version of timthumb php class

有人知道着名的PHP類“timthumb”的ASP.Net版本嗎? 只需要一個可以在同一行“timthumb”中工作的腳本,並為任何大小的圖像生成高質量的基於方形或比率的縮略圖。

這是php類的鏈接: http//www.darrenhoyt.com/2008/04/02/timthumb-php-script-released/

我為你編寫了這個:) :)我通過嘗試http://www.binarymoon.co.uk/demo/timthumb-basic/中的所有案例進行測試,並將其與我的代碼並排進行比較。 據我所知,它基本相同。 據說它不支持'zc'標志。

我把它寫成通用處理程序(ashx文件),以便它運行得更快。 支持成像緩存,但我對其進行了評論,因為它使測試修復非常困難。 隨意取消注釋,以便長期提高性能(開頭一個塊,一個塊寫入內存流時接近結束)。

- -碼 - -

<%@ WebHandler Language="VB" Class="Thumb" %>

    Imports System
    Imports System.Web
    Imports System.Drawing
    Imports System.IO

    Public Class Thumb : Implements IHttpHandler
        Private Shared _DefaultWidth As Integer = 100
        Private Shared _DefaultHeight As Integer = 100
        Private Shared _DefaultQuality As Integer = 90

        Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
            ''check the cache for the image first
            'Dim cacheObj As Object = context.Cache("Thumb-" + context.Request.Url.ToString().ToLower())
            'If cacheObj IsNot Nothing Then
            '    Dim msCache As MemoryStream = DirectCast(cacheObj, MemoryStream)

            '    WriteImage(msCache, context)

            '    Exit Sub
            'End If

            'process request (since it wasn't in the cache)
            Dim imgPath As String = context.Request.QueryString("src")

            If String.IsNullOrEmpty(imgPath) Then
                context.Response.End()
            End If

            'get image path on server
            Dim serverPath As String = context.Server.MapPath(imgPath)
            If Not File.Exists(serverPath) Then
                context.Response.End()
            End If

            'load image from file path
            Dim img As Image = Bitmap.FromFile(serverPath)
            Dim origRatio As Double = (Math.Min(img.Width, img.Height) / Math.Max(img.Width, img.Height))

            '---Calculate thumbnail sizes---
            Dim destWidth As Integer = 0
            Dim destHeight As Integer = 0
            Dim destRatio As Double = 0

            Dim qW As String = context.Request.QueryString("w")
            Dim qH As String = context.Request.QueryString("h")

            If Not String.IsNullOrEmpty(qW) Then
                Int32.TryParse(qW, destWidth)
                If destWidth < 0 Then
                    destWidth = 0
                End If
            End If

            If Not String.IsNullOrEmpty(qH) Then
                Int32.TryParse(qH, destHeight)
                If destHeight < 0 Then
                    destHeight = 0
                End If
            End If

            'if both width and height are 0 then use defaults (100x100)
            If destWidth = 0 And destHeight = 0 Then
                destWidth = _DefaultWidth
                destHeight = _DefaultHeight

                'else, if the width is specified, calculate an appropriate height
            ElseIf destWidth > 0 And destHeight > 0 Then
                'do nothing, we have both sizes already
            ElseIf destWidth > 0 Then
                destHeight = Math.Floor(img.Height * (destWidth / img.Width))
            ElseIf destHeight > 0 Then
                destWidth = Math.Floor(img.Width * (destHeight / img.Height))
            End If

            destRatio = (Math.Min(destWidth, destHeight) / Math.Max(destWidth, destHeight))

            'calculate source image sizes (rectangle) to get pixel data from        
            Dim sourceWidth As Integer = img.Width
            Dim sourceHeight As Integer = img.Height

            Dim sourceX As Integer = 0
            Dim sourceY As Integer = 0

            Dim cmpx As Integer = img.Width / destWidth
            Dim cmpy As Integer = img.Height / destHeight

            'selection is based on the smallest dimension
            If cmpx > cmpy Then
                sourceWidth = img.Width / cmpx * cmpy
                sourceX = ((img.Width - (img.Width / cmpx * cmpy)) / 2)
            ElseIf cmpy > cmpx Then
                sourceHeight = img.Height / cmpy * cmpx
                sourceY = ((img.Height - (img.Height / cmpy * cmpx)) / 2)
            End If

            '---create the new thumbnail image---
            Dim bmpThumb As New Bitmap(destWidth, destHeight)
            Dim g = Graphics.FromImage(bmpThumb)
            g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
            g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
            g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias

            g.DrawImage(img, _
                        New Rectangle(0, 0, destWidth, destHeight), _
                        New Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel)

            '-----write out Thumbnail to the output stream------        
            'get jpeg image coded info so we can use it when saving
            Dim ici As Imaging.ImageCodecInfo = Imaging.ImageCodecInfo.GetImageEncoders().Where(Function(c) c.MimeType = "image/jpeg").First()

            'save image to memory stream
            Dim ms As New MemoryStream()
            bmpThumb.Save(ms, ici, BuildQualityParams(context))

            ''save image to cache for future use
            'context.Cache("Thumb-" + context.Request.Url.ToString().ToLower()) = ms

            'write the image out
            WriteImage(ms, context)
        End Sub

        Private Sub WriteImage(ByVal ms As MemoryStream, ByVal context As HttpContext)
            'clear the response stream
            context.Response.Clear()

            'set output content type to jpeg
            context.Response.ContentType = "image/jpeg"

            'write memory stream out
            ms.WriteTo(context.Response.OutputStream)

            'flush the stream and end the response
            context.Response.Flush()
            context.Response.End()
        End Sub

        'for adjusting quality setting if needed, otherwise 90 will be used
        Private Function BuildQualityParams(ByVal context As HttpContext) As Imaging.EncoderParameters
            Dim epParams As New Imaging.EncoderParameters(1)

            Dim q As Integer = _DefaultQuality

            Dim strQ As String = context.Request.QueryString("q")
            If Not String.IsNullOrEmpty(strQ) Then
                Int32.TryParse(strQ, q)
            End If

            epParams.Param(0) = New Imaging.EncoderParameter(Imaging.Encoder.Quality, q)

            Return epParams
        End Function

        Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property
    End Class

- -測試用例 - -

<img alt="" src="Thumb.ashx?src=~/images/castle1.jpg" /> 
<br />
<img alt="" src="Thumb.ashx?src=~/images/castle1.jpg&q=100" /> 
<br />
<img alt="" src="Thumb.ashx?src=~/images/castle1.jpg&q=10" /> 
<br />
<img alt="" src="Thumb.ashx?src=~/images/castle1.jpg&w=200" /> 
<br />
<img alt="" src="Thumb.ashx?src=~/images/castle1.jpg&h=150" /> 
<br />
<img alt="" src="Thumb.ashx?src=~/images/castle1.jpg&h=180&w=120" /> 
<br />
<img alt="" src="Thumb.ashx?src=~/images/castle1.jpg&h=80&w=210" /> 
<br />

@ Peter感謝您上面的代碼,它在我的ashx文件中完美運行。 我是一個asp.net c#開發人員,所以我已經將你的vb代碼轉換為c#並修復了我遇到的一些問題。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

namespace myProject.Handlers
{
    public class Thumb : IHttpHandler
    {
        private static int _DefaultWidth = 100;
        private static int _DefaultHeight = 100;
        private static int _DefaultQuality = 90;

        public void ProcessRequest(HttpContext context)
        {
            string imgPath = context.Request.QueryString["src"];

            if (string.IsNullOrEmpty(imgPath))
            {
                context.Response.End();
            }

            string serverPath = context.Server.MapPath(imgPath);
            if (!File.Exists(serverPath))
            {
                context.Response.End();
            }

            Image img = Bitmap.FromFile(serverPath);
            double origRatio = (Math.Min(img.Width, img.Height) / Math.Max(img.Width, img.Height));

            int destWidth = 0;
            int destHeight = 0;
            double destRatio = 0;
            double dHeight = 0;
            double dWidth = 0;

            string qW = context.Request.QueryString["w"];
            string qH = context.Request.QueryString["h"];

            if (!string.IsNullOrEmpty(qW))
            {
                Int32.TryParse(qW, out destWidth);
                if (destWidth < 0)
                {
                    destWidth = 0;
                }
            }

            if (!string.IsNullOrEmpty(qH))
            {
                Int32.TryParse(qH, out destHeight);
                if (destHeight < 0)
                {
                    destHeight = 0;
                }
            }

            if (destWidth == 0 & destHeight == 0)
            {
                destWidth = _DefaultWidth;
                destHeight = _DefaultHeight;
            }
            else if (destWidth > 0 & destHeight > 0)
            {
                //do nothing, we have both sizes already
            }
            else if (destWidth > 0)
            {
                dHeight = double.Parse(destWidth.ToString()) / double.Parse(img.Width.ToString());
                destHeight = int.Parse(Math.Floor(img.Height * dHeight).ToString());
            }
            else if (destHeight > 0)
            {
                dWidth = double.Parse(destHeight.ToString()) / double.Parse(img.Height.ToString());
                destWidth = int.Parse(Math.Floor(img.Width * dWidth).ToString());
            }

            destRatio = (Math.Min(destWidth, destHeight) / Math.Max(destWidth, destHeight));

            int sourceWidth = img.Width;
            int sourceHeight = img.Height;

            int sourceX = 0;
            int sourceY = 0;

            int cmpx = img.Width / destWidth;
            int cmpy = img.Height / destHeight;

            if (cmpx > cmpy)
            {
                sourceWidth = img.Width / cmpx * cmpy;
                sourceX = ((img.Width - (img.Width / cmpx * cmpy)) / 2);
            }
            else if (cmpy > cmpx)
            {
                sourceHeight = img.Height / cmpy * cmpx;
                sourceY = ((img.Height - (img.Height / cmpy * cmpx)) / 2);
            }

            Bitmap bmpThumb = new Bitmap(destWidth, destHeight);
            Graphics g = Graphics.FromImage(bmpThumb);
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.SmoothingMode = SmoothingMode.AntiAlias;

            g.DrawImage(img, new Rectangle(0, 0, destWidth, destHeight), new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel);

            ImageCodecInfo ici = ImageCodecInfo.GetImageEncoders().Where(c => c.MimeType == "image/jpeg").First();

            MemoryStream ms = new MemoryStream();
            bmpThumb.Save(ms, ici, BuildQualityParams(context));

            WriteImage(ms, context);
        }

        private void WriteImage(MemoryStream ms, HttpContext context)
        {
            context.Response.Clear();

            context.Response.ContentType = "image/jpeg";

            ms.WriteTo(context.Response.OutputStream);

            context.Response.Flush();
            context.Response.End();
        }

        private EncoderParameters BuildQualityParams(HttpContext context)
        {
            EncoderParameters epParams = new EncoderParameters(1);

            int q = _DefaultQuality;

            string strQ = context.Request.QueryString["q"];
            if (!string.IsNullOrEmpty(strQ))
            {
                Int32.TryParse(strQ, out q);
            }

            epParams.Param[0] = new EncoderParameter(Encoder.Quality, q);

            return epParams;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

看起來你想做這樣的事情: http//www.4guysfromrolla.com/articles/012203-1.aspx

最糟糕的情況是,timthumb是開源的,因此您可以在.NET中創建它並向世界開源! (當然,正確歸屬於原文)

http://imageresizing.net庫可以完成TimThumb腳本所做的一切以及更多功能。 它非常易於安裝和完全支持。

TimThumb:image.jpg?w = 100&h = 100&q = 90

ImageResizing.Net:image.jpg?width = 100&height = 100&quality = 100

如果你需要模仿timthumb的確切語法,請告訴我,我可以給你幾行代碼來使它工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM