Saving & resizing GIF's in dotnet - how to preseve animation?
I've written several hundred lines of image management code in my current application all of which seems to work nicely ... except that uploaded GIF's loose their animation somewhere along the line. I've traced the problem down to the point at which images are saved to disk (in order to cache them) as displaying them direct from the database (where they're stored as blobs) they seem fine.
Here's the code - there's a bunch of calls to custom objects and functions that I haven't listed but I don't believe they're relevant to the issue - I think it's somewhere in these two key function:
Private Sub CreateImageFileInCache()
Dim CMSImage As Cms.DataTransferObjects.Image = My.Application.ManagerFactory.ImageManagerInstance.ById(ImageId)
If CMSImage IsNot Nothing Then
SaveMetaInfo(CMSImage)
Using ms As New IO.MemoryStream(CMSImage.Data)
Dim expectedSize As New Drawing.Size(Width, Height)
Using img As System.Drawing.Image = resizeImage(System.Drawing.Bitmap.FromStream(ms), _
expectedSize, _
Drawing.Drawing2D.InterpolationMode.HighQualityBicubic, CMSImage.MimeType)
img.Save(ImageCachePath, GetEncoderInfo(CMSImage.MimeType), GenerateEncodingParameters)
img.Dispose()
End Using
End Using
End If
End Sub
Private Function resizeIma开发者_高级运维ge(ByVal imgToResize As System.Drawing.Image, ByVal size As System.Drawing.Size, ByVal Quality As System.Drawing.Drawing2D.InterpolationMode, ByVal format As String) As System.Drawing.Bitmap
Dim sourceWidth As Integer = imgToResize.Width
Dim sourceHeight As Integer = imgToResize.Height
Dim resizedImage As System.Drawing.Bitmap
Dim canvas As System.Drawing.Graphics
Dim calculatedSize As Drawing.Size = Global.Concrete.Base.Web.Controls.ProductImage.calculateNewImageSize(sourceWidth, sourceHeight, size)
If calculatedSize.Width > imgToResize.Width AndAlso calculatedSize.Height > imgToResize.Height Then
calculatedSize.Width = imgToResize.Width
calculatedSize.Height = imgToResize.Height
End If
resizedImage = New System.Drawing.Bitmap(calculatedSize.Width, calculatedSize.Height)
canvas = System.Drawing.Graphics.FromImage(resizedImage)
canvas.InterpolationMode = Quality
If Quality = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic Then
canvas.CompositingQuality = Drawing.Drawing2D.CompositingQuality.AssumeLinear
canvas.SmoothingMode = Drawing.Drawing2D.SmoothingMode.AntiAlias
End If
canvas.DrawImage(imgToResize, 0, 0, calculatedSize.Width, calculatedSize.Height)
canvas.Dispose()
imgToResize.Dispose()
If format.Contains("gif") Then
Dim quantizer As Concrete.Cms.ImageManipulation.OctreeQuantizer
quantizer = New Concrete.Cms.ImageManipulation.OctreeQuantizer(255, 8)
resizedImage = quantizer.Quantize(resizedImage)
End If
Return resizedImage
End Function
Any suggestions gratefully received.
EDIT: Substituting img.Save(ImageCachePath, GetFormat(MimeType)) for the three-argument call to .Save still results in a static gif.
EDIT 2: Actually doing almost anything to a GIF seems to stop it animating! Trying to resize it using Canvas, and trying to presever quality using Quantizing all seem to screw up the animations.
Cheers, Matt
OK, as far as I can make out THIS IS NOT CURRENTLY POSSIBLE. At least not with any reasonable amount of effort. It does look like it might be possible by using the resizing methods on WPF, but sadly WPF is meant for winforms rather than ASP and rendering looks like a nightmare - potential to solve it by using an Ajax updatepanel and refreshing the content for every frame of the animation as it loads. No thanks!
I find it amazing that you can't mess with an animated image at all without loosing the animation information, especially in a technology this mature!!
精彩评论