Chart to image creation is very slow (Android- aspose.cells)

Hi,


I had retrieved the chart from the existing excel file to be displayed to the user on the ImageView using these lines of codes inside an asyn task.

ImageOrPrintOptions imgOption = new ImageOrPrintOptions();
imgOption.setImageFormat(ImageFormat.getPng());

ByteArrayOutputStream bArray = new ByteArrayOutputStream();
// chart.toImage(new FileOutputStream(sdCardPath + “MyChartImage.png”), imgOption);
chart.toImage(bArray, imgOption);
byte[] bytes = bArray.toByteArray();
bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);


but it seems like, the async task is also unable to improve the performance in displaying the chart to the user. And it is also very slow whenever it comes to this line of code “chart.toImage(bArray,imgOption)”. Besides that, I had also tried using a simple chart and it seems like the performance only improve a little, not much.

May I know what should I do to fix this?

Thank you.

Regards
Jacqueline.


Hi,


We also think the Chart to Image feature needs further improvements even knowing the barriers on Android platforms. Anyways, could you post your simple Excel file containing the sample chart, so we could evaluate your issue on our end and may log a ticket for the issue into our database.

Thank you.
Hi,
Thank you for your reply.

These are the code snippets that I had used. This one is able to display retrieve the image and display it (a bit fast, but still take some time), but when I used my own chart, it is very slow.


Workbook workbook2 = new Workbook();

//Obtaining the reference of the first worksheet
WorksheetCollection worksheets = workbook2.getWorksheets();
Worksheet sheet = worksheets.get(0);

//Adding some sample value to cells
Cells cells2 = sheet.getCells();
Cell cell = cells2.get("A1");
cell.setValue(50);
cell = cells2.get("A2");
cell. setValue (100);
cell = cells2.get("A3");
cell.setValue(150);
cell = cells2.get("B1");
cell.setValue(4);
cell = cells2.get("B2");
cell.setValue(20);
cell = cells2.get("B3");
cell.setValue(50);

ChartCollection charts = sheet.getCharts();

//Adding a chart to the worksheet
int chartIndex = charts.add(ChartType.PYRAMID,5,0,15,5);
Chart chart = charts.get(chartIndex);

SeriesCollection serieses = chart.getNSeries();
serieses.add("A1:B3", true);

//Get the Chart image
ImageOrPrintOptions imgOpts = new ImageOrPrintOptions();
imgOpts.setImageFormat(ImageFormat.getPng());


ByteArrayOutputStream bArray = new ByteArrayOutputStream();
chart.toImage(bArray, imgOpts);
byte[] bytes = bArray.toByteArray();
bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);


ImageView img = new ImageView(ServerExcel_CustomViewer.this);
img.setImageBitmap(bmp);

Thank you.

Regards,
Jacqueline

Hi,


Thanks for sharing the sample code.

After an initial test, I observed the issue as you mentioned. It takes more time to render the chart image. It takes about 1.5
minutes or more time to render the image of the simplest chart using the following sample
code:
e.g
Sample code:

Workbook workbook2 = new Workbook();

//Obtaining the reference of the first worksheet
WorksheetCollection worksheets = workbook2.getWorksheets();
Worksheet sheet = worksheets.get(0);

//Adding some sample value to cells
Cells cells2 = sheet.getCells();
Cell cell = cells2.get(“A1”);
cell.setValue(50);
cell = cells2.get(“A2”);
cell. setValue (100);
cell = cells2.get(“A3”);
cell.setValue(150);
cell = cells2.get(“B1”);
cell.setValue(4);
cell = cells2.get(“B2”);
cell.setValue(20);
cell = cells2.get(“B3”);
cell.setValue(50);

ChartCollection charts = sheet.getCharts();

//Adding a chart to the worksheet
int chartIndex = charts.add(ChartType.PYRAMID,5,0,15,5);
Chart chart = charts.get(chartIndex);

SeriesCollection serieses = chart.getNSeries();
serieses.add(“A1:B3”, true);

//Get the Chart image
ImageOrPrintOptions imgOpts = new ImageOrPrintOptions();
imgOpts.setImageFormat(ImageFormat.getPng());


chart.toImage(sdCardPath + “outimg2.png”, imgOpts);

I have logged a ticket with an id “CELLSANDROID-48” for your issue. We will look into it soon.

Once we have any update on it, we will let you know here.

Thank you.

Hi,


Thank you for the prompt reply and I look forward to your update.

Thank you.

Regards,
Jacqueline

Hi,


We have evaluated your issue further. Well, the chart uses Arial font by default. Please make sure that the underlying font is installed on your Android virtual folder. Please copy Arial.ttf to the Android’s sd card file direction (e.g. /sdcard/fonts). Then use CellsHelper.setFontDir to set this directory at the start. Doing so, the performance can be improved a bit. By the way, as you might know the Android memory is limited. The pointer of large object needs to be set null if large object is not used any more. Then the large object can be released by gc in case of needing more memory while processing. Please see the sample code below and try it on your end (after copying the Arial.ttf font to your fonts folder) if it makes any difference.
e.g
Sample code:

CellsHelper.setFontDir(sdcardPath + “/fonts”); //sdcardPath: e.g. "/sdcard"
Workbook workbook2 = new Workbook();

//Obtaining the reference of the first worksheet
WorksheetCollection worksheets = workbook2.getWorksheets();
Worksheet sheet = worksheets.get(0);

//Adding some sample value to cells
Cells cells2 = sheet.getCells();
Cell cell = cells2.get(“A1”);
cell.setValue(50);
cell = cells2.get(“A2”);
cell. setValue (100);
cell = cells2.get(“A3”);
cell.setValue(150);
cell = cells2.get(“B1”);
cell.setValue(4);
cell = cells2.get(“B2”);
cell.setValue(20);
cell = cells2.get(“B3”);
cell.setValue(50);

ChartCollection charts = sheet.getCharts();

//Adding a chart to the worksheet
int chartIndex = charts.add(ChartType.PYRAMID,5,0,15,5);
Chart chart = charts.get(chartIndex);

SeriesCollection serieses = chart.getNSeries();
serieses.add(“A1:B3”, true);


//Get the Chart image
ImageOrPrintOptions imgOpts = new ImageOrPrintOptions();
imgOpts.setImageFormat(ImageFormat.getPng());



ByteArrayOutputStream bArray = new ByteArrayOutputStream();
chart.toImage(bArray, imgOpts);
byte[] bytes = bArray.toByteArray();
bArray.close();
bArray = null;

bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
bytes = null;


ImageView img = new ImageView(ServerExcel_CustomViewer.this);
img.setImageBitmap(bmp);

Let us know how it goes on your end.

Thank you.

Hi,


Can you please send me the “Arial.ttf” file to me so that I can test it?

Thank you.

Regards.
Jacqueline

Hi,


Well, you may copy the font from Windows. Anyways, I have attached the zipped archive containing the arial fonts for your requirements.

Thank you.

Hi,


Sorry for the late reply. I had tried and the performance had improved a lot compared to the last time.
Thank you very much for your support/assistance. I really appreciate it very much. =)

Thank you.

Regards
Jacqueline.

Hi Jacqueline,

Thanks for your feedback and using Aspose.Cells.

It is good to know that after adding fonts, the performance of your application has improved. Please note, whenever you try to convert your chart or worksheet into images or try to autofit rows or columns, you must have already added the fonts used in your Excel file in some directory and set your font directory using the CellsHelper.setFontDir() method. It will increase the performance and also improve the results of your output. Let us know if you encounter any other issue, we will be glad to look into it and help you further.

Hi,


Thank you for the explanations. I would also like to know how do I retrieve the file arial.ttf from the raw/asset folder instead of from the sdCard. May I know how do I write the code? as “CellsHelper.setFontDir()” is for directory, and so when I tested it with this code which is from the raw folder
String path = “android.resource://”+ServerExcel_CustomViewer.this.getPackageName()+"/raw/"+“arial_ttf”;
it does not work.

Thank you.
Regards,
Jacqueline.

Hi Jacqueline,

Thanks for your posting and using Aspose.Cells for Android.

Please use some folder inside the SD Card and place your fonts there. Placing fonts in asset folder will not work.

Let us know if you have any other question. We will look into it and help you asap.

Hi,


I see, thank you for the prompt reply, so I will have to put the fonts into the asset folder and then copy it out from the asset folder into the SD card in order to use it. As for the Fonts I can do that, but may I know what about the aspose license ? According to the guide given in the aspose website, it is also the same, it is retrieving the license file from the SD card, so may I know if it is possible to read the aspose license directly from the asset/raw folder instead of from the SD card? Because I wouldn’t want the users to be able to get that license file from their SD card or so, so this method of mine which copies files from the asset folder into the SD card will not be appropriate for it.

Thank you.

Regards,
Jacqueline

@jacqueline_chin1128,
You may please refer to the following article to protect your license from being leaked or stolen:
License Protection.

Feel free to write us back if you have any other query in this regard.

Hi,


Thank you for the sample codes and also your support/assistance. You guys are awesome!!. I really appreciate it very much. And I have one last question, may I know if, every time I create an excel file/ convert the graph into an image using aspose, I will be required to set the license “lic.setLicense(stream);” in order remove the watermark/remove the limitations?.

Thank you,

Regards,
Jacqueline.

Hi Jacqueline,

Thanks for your posting and using Aspose.Cells.

You will have to set it only once per application. Set it before using any other Aspose.Cells API.

If you will set it every time, it will not harm your application, because license code will automatically check if the license is already set and will not execute again.

Also, you can check if your license is set or not using License.isLicenseSet() static method. If your license is already set, it will return true and if it is not already set, it will return false.

So you can write a license setting code like this

Java


//Check if license is already set or not

if(License.isLicenseSet()==false)

{

//Set your license

License lic = new License();

lic.setLicense(licStream);

}



Hi Shakeel,


Thank you very much for the information. I appreciate it =).

Regards,
Jacqueline.