我想创建一个包含2张图片的pdf。其中一个图像是文本,另一个是在第一个图像之上绘制的水印。好吧,当我加载第一张图片时,一切都还可以,但之后我尝试加载水印图像并获得“内存不足”#34;例外。我有记忆(打印内存使用量大约是20MB)并且可以在我的计算机上打开图像(我使用谷歌中的图像进行测试直到我没有得到真实的图像)。
我得到异常的代码就是这个:
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;
}
}
我已经看过像我这样的其他问题,但是:
答案 0 :(得分:7)
您正在构建对象
using (System.Drawing.Image imgOriginal = System.Drawing.Image.FromFile(sOriginalPath, true))
然后你要归还它......但是它已经被处理掉了......你需要通过用一个使用来展开它来处理它...对于处理这个对象需要的任何消耗。
bitmap
也是内存泄漏,需要隐式调用using
或dispose
。
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;
}
我已经测试了下面的内容,它按预期工作。
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;
}
}
}
答案 1 :(得分:1)
我发现在程序的先前函数中,文件是在与水印图像完全相同的路径中创建的,因此当我尝试将其打开为图像时,它给了我一个错误。
解决了这个问题之后我注意到我的代码还有另外一个问题,我的imgOriginal被退回但因为我正在使用
using (System.Drawing.Image imgOriginal = System.Drawing.Image.FromFile(sOriginalPath, true))
物体被丢弃,所以我失去了我的形象。为了解决这个问题,我将我的功能更新为:
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;
}
答案 2 :(得分:0)
首先转换字节[]格式后,转换base64格式尝试下面的代码可能会解决你的问题,
response = urllib2.urlopen(paths)
zipcontent= response.read()
with open(tempDownloadPath, 'wb') as f:
f.write(zipcontent)