webForumDet fria alternativet

Skapa bilder "on the fly" ger felet: out of memory

.NET

7 svar · 562 visningar · startad av mattiasjarnhall

Medlem sedan apr. 2001126 inlägg
Frågan#1

kör följande script för att skapa thumbnails "on the fly":

<%@ Import Namespace=System.Drawing %>
<%@ Import Namespace=System %>
<%@ Import Namespace=System.Web %>

<script language="VB" runat="server">

Sub Page_Load(Sender As Object, E As EventArgs)
  
Dim orginalimg, thumb As System.Drawing.Image
Dim FileName As String
Dim inp As New IntPtr()
Dim width, height As Integer
Dim rootpath As String

rootpath = Server.MapPath("/") ' Get Root Application Folder
FileName = rootpath & Request.QueryString("FileName") ' Root Folder + FileName
'Response.Write(FileName)
'Response.End

'Try
orginalimg = orginalimg.FromFile(FileName) ' Fetch User Filename
'Catch
'orginalimg = orginalimg.FromFile(rootpath & "grfx/flaggor/sverigefla.gif") ' Fetch error.gif
'End Try

' Get width using QueryString.
If Request.QueryString("width") = Nothing Then
width = orginalimg.Width ' Use Orginal Width. 
ElseIf Request.QueryString("width") = 0 Then ' Assign default width of 100.
width = 100
Else
width = Request.QueryString("width") ' Use User Specified width.
End If

' Get height using QueryString.
If Request.QueryString("height") = Nothing Then
height = orginalimg.Height ' Use Orginal Height.
ElseIf Request.QueryString("height") = 0 Then ' Assign default height of 100.
height = 100
Else
height = Request.QueryString("height") ' Use User Specified height.
End If

thumb = orginalimg.GetThumbnailImage(width, height, Nothing, inp)

' Sending Response JPEG type to the browser. 
If lCase(Right(FileName,3)) <> "gif" Then
	Response.ContentType = "image/jpeg"
	thumb.Save(Response.OutputStream, Imaging.ImageFormat.Jpeg)
Else
	Response.ContentType = "image/Gif"
	thumb.Save(Response.OutputStream, Imaging.ImageFormat.Gif)
End If

' Disposing the objects.
orginalimg.Dispose()
thumb.Dispose()

End Sub
</script>

Jag anropar scriptet med följande syntax: http://www.sidan.nu/thumbnails.aspx?FileName=bildMapp/bilden.jpg&width=100&height=100

Detta funkar fint i bland, och sämre andra gånger. Felmeddelandet som dyker upp är:

Out of memory.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.OutOfMemoryException: Out of memory.

Är bilden för stor för att läsas in i minnet? Den är inte över 1MB.. så varför blir det såhär? Var sätts dessa storleksbegränsningar? Och hur kan jag påverka det?

/Mattias

Medlem sedan apr. 20012 266 inlägg
#2

Hade ett liknande problem förut och det var när jag försökte skapa .png filger. Då kunde jag inte skriva bilden direkt till Response.OutputStream utan behövde spara bilden i en MemoryStream som jag senare skrev till Response.OutputStream.

Medlem sedan apr. 2001126 inlägg
#3

Renholm... hur skulle det se ut i kod? :)

Medlem sedan apr. 20012 266 inlägg
#4

Här är ett fungerande exempel på hur man hämtar en bild och sedan skriver på lite text, inte exakt vad du ska göra men du bör "hajja" principen.

using System;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

using Renholm.CMS.Modules.Graphic.Configurations;

namespace Renholm.CMS.Modules.Graphic.HttpHandler
{
	public class Tab : IHttpHandler
	{
		public void ProcessRequest(HttpContext context) 
		{
			if (context.Request.QueryString["state"] != null)
			{
				string text = context.Request.RawUrl;
				text = text.Substring(text.LastIndexOf("/") + 1,text.LastIndexOf(".") - text.LastIndexOf("/") - 1);
				text = text.ToUpper();

				string cacheName;
				bool active;

				if (context.Request.QueryString["state"] == "1")
				{
                    active = true;
					cacheName = text + "active";
				}
				else
				{
					active = false;
					cacheName = text + "deactive";
				}

				if (context.Cache[cacheName] == null)
				{
					GenerateImage(text, active, cacheName);
				}

				context.Response.ContentType = "image/png";
				((MemoryStream)context.Cache[cacheName]).WriteTo(context.Response.OutputStream);
			}
			else
			{
				context.Response.Write("State is missing.");
				context.Response.End();
			}
		}

		private void GenerateImage(string text, bool active, string cacheName)
		{
			string fileName;

			if (active)
			{
				fileName = HttpContext.Current.Server.MapPath(((Settings)Config.GetSettings()).TabImageActive);
			}
			else
			{
				fileName = HttpContext.Current.Server.MapPath(((Settings)Config.GetSettings()).TabImage);
			}

			Font fontSettings = new Font("kroeger 05_63", 8);

			FileStream fs = new FileStream(fileName, FileMode.Open);

			Bitmap objBitmap = new Bitmap(fs);
			Graphics objGraphics = Graphics.FromImage(objBitmap);
			int width = objBitmap.Width, height = objBitmap.Height;

			StringFormat stringFormat = new StringFormat();
			stringFormat.Alignment = StringAlignment.Center;
			stringFormat.LineAlignment = StringAlignment.Center;
				
			objGraphics.DrawString(text, fontSettings, new SolidBrush(Color.White), 
				new Rectangle(0, 0, width, height), stringFormat);
			[b]	
			MemoryStream ms = new MemoryStream();
			objBitmap.Save(ms, ImageFormat.Png);
[/b]

			objGraphics.Dispose();
			objBitmap.Dispose();
			fs.Close();

			HttpContext.Current.Cache.Insert(cacheName, ms, new System.Web.Caching.CacheDependency(fileName));

		}

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

Det i fetstil som du bör vara intresserad av, resten är lite cachning samt allt ligger i en httphandler.

Medlem sedan okt. 20005 273 inlägg
#5

Nu väcker jag denna tråd. :)
Om man skriva lite text i en bild. Var ska man lägga typsnitten då?

mv icaaq

Medlem sedan apr. 20012 266 inlägg
#6

På servern vore väl lämpligt, eftersom bilden genereras på serversidan.

Medlem sedan juli 20022 537 inlägg
#7

Om inte teckensnittet finns installerat på servernkan du använda klassen PrivateFontCollection som ligger i System.Drawing.Text och sedan använda AddFontFile(ByVal Filename As String) för att ange sökvägen till teckensnittet.

Medlem sedan okt. 20005 273 inlägg
#8

Hur gör jag för att använda andra typsnitt än *.TTF??

mv icaaq

267 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
122 ms — deklarationer (db)
0 ms — hämta statistik (cache)
142 ms — hämta tråd, inlägg och bilagor (db)
122 ms — ändringar (db)