Convert Word Document to HTML and Set Images using Streams in IImageSavingCallback callback (Java) | Empty Buffer in ImageSavingArgs

Hi. I trying to save image for html

To do this, use the following code

In HtmlSaveOptions set folowing options

htmlSaveOptions = new HtmlSaveOptions(SaveFormat.HTML);
htmlSaveOptions.setPrettyFormat(true);
htmlSaveOptions.setExportListLabels(ExportListLabels.AS_INLINE_TEXT);
htmlSaveOptions.setExportHeadersFootersMode(ExportHeadersFootersMode.NONE);
htmlSaveOptions.setExportImagesAsBase64(false);
htmlSaveOptions.setImageResolution(IMAGE_UPLOAD_RESOLUTION_DPI);

And add callback

htmlSaveOptions.setImageSavingCallback(imageSavingArgs -> {
    
    if (imageSavingArgs.isImageAvailable()){
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        imageSavingArgs.setImageStream(byteArrayOutputStream);

        try (InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.)) {
            amazonS3.putObject(embeddedImageStorageS3Bucket, imageSavingArgs.getImageFileName(),
                inputStream, new ObjectMetadata());
        } catch (IOException e){
            log.error("Error in saving embedded image to S3, object => " + imageSavingArgs.getImageFileName(), e);
        }
    }
});

But byteArrayOutputStream is always empty. Why?

Aspose.Word Java 19.5 Java 8

@ValorVl,

To ensure a timely and accurate response, please ZIP and attach the following resources here for testing:

  • Your simplified input Word document you are getting this problem with
  • Aspose.Words for Java 19.9 generated output document (if any) showing the undesired behavior
  • Please also create a standalone simple Java application (source code without compilation errors) that helps us to reproduce your current problem on our end and attach it here for testing. Please do not include Aspose.Words JAR files in it to reduce the file size.

As soon as you get these pieces of information ready, we will start investigation into your issue and provide you more information. Thanks for your cooperation.

Hi

aspose_bug_example.zip (23.8 KB)

Unfortunately, I can’t use the version you specified, since my license does not allow this :frowning:

The test project is attached.

@ValorVl,

We have logged this problem in our issue tracking system. Your ticket number is WORDSNET-19377. We will further look into the details of this problem and will keep you updated on the status of the linked issue. We apologize for any inconvenience.

@ValorVl,

Regarding WORDSNET-19377, we have completed the work on this issue and concluded to close this issue with “not a bug” status. Please note that IImageSavingCallback.ImageSaving is used only to provide a stream to Aspose.Words. Actual writing of an image to the stream happens after the IImageSavingCallback.ImageSaving method returns control back to Aspose.Words. So the correct way of using streams in IImageSavingCallback is one of the following:

private void Write() {
    try {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("simple_empty_document_with_image.docx");
        if (resourceAsStream != null) {
            Document document = new Document(resourceAsStream);

            HtmlSaveOptions htmlSaveOptions = makeSaveOptions();

            htmlSaveOptions.setImageSavingCallback(imageSavingArgs -> {
                imageSavingArgs.setImageStream(new FileOutputStream("/aspose_bug_example/test.jpg"));
            });
            System.out.println(document.toString(htmlSaveOptions));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

OR

private void Write() {
    try {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("simple_empty_document_with_image.docx");
        if (resourceAsStream != null) {
            Document document = new Document(resourceAsStream);
            HtmlSaveOptions htmlSaveOptions = makeSaveOptions();
            htmlSaveOptions.setImageSavingCallback(new ImageSaveCallBack1());
            System.out.println(document.toString(htmlSaveOptions));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

class ImageSaveCallBack1 implements IImageSavingCallback {

    @Override
    public void imageSaving(ImageSavingArgs imageSavingArgs) throws Exception {
        imageCount++;
        imageSavingArgs.setImageStream(new FileOutputStream(String.format("/aspose_bug_example/test%d.jpg", imageCount)));
    }

    private int imageCount;
}

OR

private void Write() {
    try {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("simple_empty_document_with_image.docx");
        if (resourceAsStream != null) {
            Document document = new Document(resourceAsStream);
            HtmlSaveOptions htmlSaveOptions = makeSaveOptions();
            ImageSaveCallBack2 callback = new ImageSaveCallBack2();
            htmlSaveOptions.setImageSavingCallback(callback);
            System.out.println(document.toString(htmlSaveOptions));
            callback.writeAllList();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

class ImageSaveCallBack2 implements IImageSavingCallback {

    @Override
    public void imageSaving(ImageSavingArgs imageSavingArgs) throws Exception {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        imageSavingArgs.setImageStream(byteArrayOutputStream);
        imageSavingArgs.setKeepImageStreamOpen(true);
        streams.add(byteArrayOutputStream);
    }

    public void writeAllList() {
        // Save image streams to files or process them somehow else.
        for (int i = 0; i < streams.size(); i++) {
            try (FileOutputStream fos = new FileOutputStream(String.format("/aspose_bug_example/test%d.jpg", i))) {
                fos.write(streams.get(i).toByteArray());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private List<ByteArrayOutputStream> streams = new ArrayList<>();
}