简体   繁体   English

asp.net版本的timthumb php类

[英]asp.net version of timthumb php class

Anyone know of a ASP.Net version of the famous PHP class "timthumb"? 有人知道着名的PHP类“timthumb”的ASP.Net版本吗? Just need a script which will work in the same line of "timthumb" and produce square or ratio based thumbnails with good quality for any sized images. 只需要一个可以在同一行“timthumb”中工作的脚本,并为任何大小的图像生成高质量的基于方形或比率的缩略图。

Here is the link to the php class: http://www.darrenhoyt.com/2008/04/02/timthumb-php-script-released/ 这是php类的链接: http//www.darrenhoyt.com/2008/04/02/timthumb-php-script-released/

I wrote this up just for you :) ... I tested it by trying all of the cases in http://www.binarymoon.co.uk/demo/timthumb-basic/ and comparing it visually side by side with my code. 我为你编写了这个:) :)我通过尝试http://www.binarymoon.co.uk/demo/timthumb-basic/中的所有案例进行测试,并将其与我的代码并排进行比较。 As far as I can tell it's basically identical. 据我所知,它基本相同。 With that said it does not support the 'zc' flag. 据说它不支持'zc'标志。

I wrote it as a generic handler (ashx file) so that it should run faster. 我把它写成通用处理程序(ashx文件),以便它运行得更快。 Imaging caching is supported but I commented it out since it makes testing fixes very tough. 支持成像缓存,但我对其进行了评论,因为它使测试修复非常困难。 Feel free to uncomment it for improved performance over the long run (one block right at the beginning and one near the end when it writes it to the memory stream). 随意取消注释,以便长期提高性能(开头一个块,一个块写入内存流时接近结束)。

---Code--- - -码 - -

<%@ 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

---Test Cases--- - -测试用例 - -

<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 thank you for your code above, it works perfectly in my ashx file. @ Peter感谢您上面的代码,它在我的ashx文件中完美运行。 I'm a asp.net c# developer so I have converted your vb code to c# and have fixed up some issues that I encountered. 我是一个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;
            }
        }
    }
}

Looks like you want to do something like this: http://www.4guysfromrolla.com/articles/012203-1.aspx 看起来你想做这样的事情: http//www.4guysfromrolla.com/articles/012203-1.aspx

Worst case, timthumb is open-source, so you can create it in .NET and open-source it to the world! 最糟糕的情况是,timthumb是开源的,因此您可以在.NET中创建它并向世界开源! (with proper attribution to the original, of course) (当然,正确归属于原文)

The http://imageresizing.net library does everything the TimThumb script does and more. http://imageresizing.net库可以完成TimThumb脚本所做的一切以及更多功能。 It's very easy to install, and fully supported. 它非常易于安装和完全支持。

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

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

If you need to mimic the exact syntax of timthumb, let me know and I can give you a couple of lines of code that will make it work. 如果你需要模仿timthumb的确切语法,请告诉我,我可以给你几行代码来使它工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM