Reputation: 1103
I wanna create a pdf with 2 images. One of the image is a text and the other is a watermark to draw on top of the first one. Well when I load the first image everything is ok but then I try to load the watermark image and get the "Out of Memory" exception. I've got memory (printed the memory usage was like 20MB) and can open the image in my computer (I'm using one I took from google just to test until I don't get the real one).
The code where I get the exception is this one:
using (System.Drawing.Image imgOriginal = System.Drawing.Image.FromFile(sOriginalPath, true))
{
using (System.Drawing.Image imgLogo = System.Drawing.Image.FromFile(sLogoPath, true)) //This is where it throws the exception
{
using (Graphics gra = Graphics.FromImage(imgOriginal))
{
Bitmap bmLogo = new Bitmap(imgLogo);
int nWidth = bmLogo.Size.Width;
int nHeight = bmLogo.Size.Height;
int nLeft = (imgOriginal.Width / 2) - (nWidth / 2);
int nTop = (imgOriginal.Height / 2) - (nHeight / 2);
gra.DrawImage(bmLogo, nLeft, nTop, nWidth, nHeight);
}
return imgOriginal;
}
}
I've seen the other questions like mine but:
Can you help me? Thanks :)
Upvotes: 3
Views: 10209
Reputation: 18853
You are building an object
using (System.Drawing.Image imgOriginal = System.Drawing.Image.FromFile(sOriginalPath, true))
Then you are returning it...but it is already disposed of...you need to not dispose of the object by unwrapping it with a using...whatever consumes this will need to dispose of the object.
bitmap
is also a memory leak and needs to be wrapped with a using
or dispose
called implicitly.
public System.Drawing.Image GetImage(string sOriginalPath, string sLogoPath)
{
System.Drawing.Image imgOriginal = System.Drawing.Image.FromFile(sOriginalPath, true);
using (System.Drawing.Image imgLogo = System.Drawing.Image.FromFile(sLogoPath, true)) //This is where it throws the exception
{
using (Graphics gra = Graphics.FromImage(imgOriginal))
{
using(Bitmap bmLogo = new Bitmap(imgLogo))
{
int nWidth = bmLogo.Size.Width;
int nHeight = bmLogo.Size.Height;
int nLeft = (imgOriginal.Width / 2) - (nWidth / 2);
int nTop = (imgOriginal.Height / 2) - (nHeight / 2);
gra.DrawImage(bmLogo, nLeft, nTop, nWidth, nHeight);
}
}
}
return imgOriginal;
}
I've tested the below and it worked as expected.
using System.Drawing;
namespace SO_Test
{
class Program
{
static void Main(string[] args)
{
using(Image newImage = GetImage("C:\\Users\\username\\Pictures\\image.png", "C:\\Users\\username\\Pictures\\watermark.jpg"))
{
newImage.Save("C:\\Users\\username\\Pictures\\newImage.png");
}
}
static Image GetImage(string sOriginalPath, string sLogoPath)
{
Image imgOriginal = Image.FromFile(sOriginalPath, true);
using (Image imgLogo = Image.FromFile(sLogoPath, true)) //This is where it throws the exception
{
using (Graphics gra = Graphics.FromImage(imgOriginal))
{
using (Bitmap bmLogo = new Bitmap(imgLogo))
{
int nWidth = bmLogo.Size.Width;
int nHeight = bmLogo.Size.Height;
int nLeft = (imgOriginal.Width/2) - (nWidth/2);
int nTop = (imgOriginal.Height/2) - (nHeight/2);
gra.DrawImage(bmLogo, nLeft, nTop, nWidth, nHeight);
}
}
}
return imgOriginal;
}
}
}
Upvotes: 8
Reputation: 1103
Well I found out that in previous functions of the program a file was being created in the exact same path as the watermark image and so when I tried to open it up as a image it gave me an error.
After solving this problem I notice my code had another problem, my imgOriginal was being returned but because I was using the
using (System.Drawing.Image imgOriginal = System.Drawing.Image.FromFile(sOriginalPath, true))
the object was being disposed and so I was loosing my image. To solve this I updated my function to this:
public static String WatermarkFromFile(string sOriginalPath, string sLogoPath)
{
using (System.Drawing.Image imgOriginal = System.Drawing.Image.FromFile(sOriginalPath, true))
{
using (System.Drawing.Image imgLogo = System.Drawing.Image.FromFile(sLogoPath, true))
{
using (Graphics gra = Graphics.FromImage(imgOriginal))
{
Bitmap bmLogo = new Bitmap(imgLogo);
int nWidth = bmLogo.Size.Width;
int nHeight = bmLogo.Size.Height;
int nLeft = (imgOriginal.Width / 2) - (nWidth / 2);
int nTop = (imgOriginal.Height / 2) - (nHeight / 2);
gra.DrawImage(bmLogo, nLeft, nTop, nWidth, nHeight);
}
string name = Path.GetFileName(sOriginalPath);
string id = Guid.NewGuid().ToString("N");
string sImage = ConfigurationManager.AppSettings["ApplicationPath"] + "\\watermark_" + id + "_" + name;
imgOriginal.Save(sImage, imgOriginal.RawFormat);
return sImage;
}
}
return null;
}
Upvotes: 1
Reputation: 1530
first convert Byte[] format after that conver base64 format try below code may its solve your problem,
using (Graphics gra = Graphics.FromImage(imgOriginal))
{
Bitmap bmLogo = new Bitmap(imgLogo);
int nWidth = bmLogo.Size.Width;
int nHeight = bmLogo.Size.Height;
int nLeft = (imgOriginal.Width / 2) - (nWidth / 2);
int nTop = (imgOriginal.Height / 2) - (nHeight / 2);
gra.DrawImage(bmLogo, nLeft, nTop, nWidth, nHeight);
// Convert the image to byte[]
System.IO.MemoryStream stream = new System.IO.MemoryStream();
bitmap.Save(bmLogo, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] imageBytes = bmLogo.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
// Write the bytes (as a Base64 string
return base64String;
}
Upvotes: 0