Problem inserting EMF images using Memory Stream object


#1

Hello All,

I am trying to insert EMF(Enhanced metafile images) in to Excel worksheet. We have saved these metafiles in the database, I am reading them, constructing a Memory Stream object and passing as a parameter to the Worksheet.Pictures.Add method. It thorws the following exception when I try to output the generated excel file to webclient.

System.Exception: Unknown error
at Aspose.Cells.Record.?.?(Worksheet ?, Int32 ?, Int32 ?, Int32 ?, Int32 ?, Int32 ?)
at Aspose.Cells.Worksheet.?(? ?)
at Aspose.Cells.Worksheets.?(? ?)
at Aspose.Cells.Worksheets.?(FileFormatType ?)
at Aspose.Cells.Worksheets.?(Stream ?, FileFormatType ?)
at Aspose.Cells.Worksheets.?(String ?, SaveType ?, FileFormatType ?, HttpResponse ?)
at Aspose.Cells.Excel.Save(String fileName, SaveType saveType, FileFormatType fileFormatType, HttpResponse response)

The code for image insertion is below

MemoryStream msCurveFitImage = new MemoryStream((byte[])orImgReader.GetOracleLob(0).Value);

int iPicId = xlActWorkSheet.Pictures.Add(iXlCurrRowNum,iColNo,msCurveFitImage);

// int iPicId = xlActWorkSheet.Pictures.Add(iXlCurrRowNum,iColNo,@"c:\test.emf");

Picture xlPicture = xlActWorkSheet.Pictures[iPicId];

xlPicture.Left = 1;

xlPicture.Top = iCurveFitXPos;

xlPicture.Placement = PlacementType.MoveAndSize;

msCurveFitImage.Close();

The image is storead as Oracle BLOB. If I use "PNG" image instead of "EMF" image data, above code works,

the output file gets generated. It fails only if I try to insert EMF image.

I was having older version of Aspose.Excel, even after upgrading to latest version 3.7.0.2 same problem persist.

If I pass in file name of an EMF image, then the code works fine and output file gets generated. It fails only when I use Memory Stream object.

One thing I noticed when I pass EMF image file name is that, the EMF images are not stored in the Native form. I think they are converted to Bitmap/PNG format. Actually Excel can handle EMF files in Native form. I don't know why this conversion is taking place. The reason I am adding EMF file to Excel is that, they are scaleable. Since the library is converting them to Bitmap/PNG it beats the very purpose of adding EMF file. Open excel doument. Add an EMF picture object and save the excel document. Open the saved excel, EMF picture will still be in the native form and you can scale it.

I am attaching a sample EMF metafile.

Thanks,

Raj


#2

Hi Raj,

For this exception problem, please try this attached fix.

Aspose.Cells does convert EMF file into PNG format. In MS Excel, EMF file is compressed. However I don't figure out the compress algorithm. So I just convert them to PNG files.


#3

Hi Laurence ,

Thanks for the reply. I used your new .dll library. The but same problem persist.

Here is the exception log

System.Exception: Unknown error
at Aspose.Cells.Record.?.?(Worksheet ?, Int32 ?, Int32 ?, Int32 ?, Int32 ?, Int32 ?)
at Aspose.Cells.Worksheet.?(? ?)
at Aspose.Cells.Worksheets.?(? ?)
at Aspose.Cells.Worksheets.?(FileFormatType ?)
at Aspose.Cells.Worksheets.?(Stream ?, FileFormatType ?)
at Aspose.Cells.Worksheets.?(String ?, SaveType ?, FileFormatType ?, HttpResponse ?)
at Aspose.Cells.Excel.Save(String fileName, SaveType saveType, FileFormatType fileFormatType, HttpResponse response)

One weired thing is that, earlier I was able to Add "PNG" images using MemoryStream. From yesterday afternoon even that has stopped working. Before that I used to get exception only when adding EMF image through stream. But now I always get exception when I am adding any type images through memory stream. But the same thing works when I add the images throuhg a file.(Passing file name) instead of memory stream. I don't understand why it is failing when I try to add through the stream, because when I pass the file name, you basically create a input stream from that file.

Can you please have a look at this one. I need this working ASAP.

Thanks,

Raj


#4

Hi Raj,

I use the following code to test this feature and don't find any problem.

Aspose.Cells.License license = new Aspose.Cells.License();
//set License
license.SetLicense("d:\\lic\\Aspose.Custom.5744.lic");

Excel excel = new Excel();

excel.Open("d:\\test\\book1.xls");


FileStream fs = File.OpenRead("d:\\test\\test.emf");

byte[] data = new Byte[fs.Length];
fs.Read(data, 0, data.Length);
fs.Close();

MemoryStream stream = new MemoryStream(data);



excel.Worksheets[0].Pictures.Add(2, 2, stream);

fs = File.OpenRead("d:\\logo.jpg");

data = new Byte[fs.Length];
fs.Read(data, 0, data.Length);
fs.Close();

MemoryStream stream2 = new MemoryStream(data);


excel.Worksheets[0].Pictures.Add(12, 2, stream2);



excel.Save("abc.xls", SaveType.OpenInExcel, FileFormatType.Default, this.Response);

Please call MemoryStream.Close method after calling Excel.Save method.

If you still find this problem, could you create a simple project to show it? Thank you very much.


#5

Hi Laurence,

Thanks for you suggestion. The code now works. I was closing the memory stream object after adding as a picture to the cell. Now I have removed memory stream close call. I thought I can close memory stream object as I have already added through Pictures.Add method and library will read the contents of memory stream and uses the data to populate the image object.

But it seems like you are saving only the Memory stream pointer, not the data. My question is, I have to add couple of thousands (around 5000 - 15000)of pictures to the excel work sheet. I don't know whether I can have so many memory stream object opened at any given time? Do you know is there any limit on the number stream object opened?? I have tested with 6500 images. I works with out problem.

Iam wondering why the conents of the memory stream object is not stored immeidately. Instead of copying the data, your are just saving the pointer and using it later when you are trying to generate the output? Now I have to keep track of all the memory stream object that I have created and has to call Close on them, otherwise they hold up resources.

Is there any plan to change this behavior?

What about the EMF file support in the Native format? Are there any plans to support it in the near future. We very much need this feature. Does Microsoft not revealing the compression format of the EMF file? Is there any other way I can add EMF files in native format to the Excel?

Thanks,

Raj


#6

Hi Raj,

About adding pictures from streams, I think you are right. Keeping track of all stream objects is unneeded and tends to cause problem. Please try this attached fix. Now you can close stream objects immediately after adding them to pictures collections.

About EMF native format, I don't have plan to support it in a short time. I don't find detail information on how MS compress EMF files. A workaround is that you put all emf files in a template file. Aspose.Cells can hold them well.


#7

Hi Laurence,

Thanks for providing the fix. It works great.

This just fixed the image insertion problem, but my real requirement is to insert EMF in it's native format.

This is a very high priority requirement for our client. Currently I am insert PNG images of size 200x125. When user wants to see the more details, they will re-size the image. Since it is a PNG it is not scaling that good. If we put EMF image, then scaling works perfectly and user will be happy.

Is there any way to make supporting of EMF images in native form a High priority to implement? If you want I can ask my client to contact your Sales team. We need this feature badly.

You have mentioned that, you don't know the compression format the Microsoft is using for EMF images. I tested opening a Excel file in OpenOffice Calc. It opens and displays Excel file containg Metafiles(EMF) properly. Since this is a open source you might get the algorithm they are using to read the microsoft metafiles.

Thanks,

Raj


#8

Hi Raj,

Thanks for you information. I will put this feature in the first of my work list. However, this feature is still complex for us. I estimate that it will take about 4-6 weeks to make this feature.


#9

Please try this attached fix. Now it supports to embed EMF files in its native format.