Skip to content

Commit

Permalink
background images based on embedded images and data-url #1175 (#1181)
Browse files Browse the repository at this point in the history
1. Enhancement of background image handling

The change includes the enhancement that BIRT can handle background images based on the three source types

    URL
    Data-URL
    Report embedded images

The new option is given for:

    MasterPage
    Grid
    Table
    Row
    Cell
    TextElements
    all elements which use backgroundImage

The main changes are given on the "BackgroundImageInfo.java" and "BackgroundImageType.java".
What is important that I enhanced the constructors to but the necessary information to the background-image-object
to have all information to create the background image.

In addition to it, I made the property "backgroundImageType" accessible, which was the original design
but not fully implemented to use it on the background image side.

In addition to it, I enhanced the designer to display the images.
On the emitter side, I enhanced the HTML emitter and the PDF emitter to show the images.

Test cases of the change - done with the all-in-one-launch:
main test 1: MasterPages with all three types of background image source
main test 2: grid with grid-row-cell background images with all three types of background image source
main test 3: different text elements with all three types of background image source
main test 4: "data table with JavaScript image setting" with all three types of background image source

Attached you will find my test reports: images.zip

2. Fixing of warning/java documentation
Many of these classes had a lot of warnings based on missing java-doc, e.g., the constant-classes
and also the interface classes. I added the according comments.
I also solved some warnings based on constant usage and the render-option-hints on the HTML emitter.
  • Loading branch information
speckyspooky authored Jan 24, 2023
1 parent d5a4ef1 commit 85a0fb5
Show file tree
Hide file tree
Showing 54 changed files with 6,715 additions and 1,284 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Base64.Decoder;
import java.util.List;

import org.apache.batik.transcoder.TranscoderException;
Expand All @@ -50,9 +51,11 @@ public class ImageManager {

private static final String EMBEDDED_SUFFIX = ".Embedded."; //$NON-NLS-1$

private static final String DATA_PROTOCOL = "data:";

private static final ImageManager instance = new ImageManager();

private List invalidUrlList = new ArrayList();
private List<String> invalidUrlList = new ArrayList<String>();

private String resourcesRootPath = "";

Expand All @@ -73,7 +76,7 @@ public static ImageManager getInstance() {
*
* @param handle
* @param uri
* @return
* @return Return the image
*/
public Image getImage(ModuleHandle handle, String uri) {
return getImage(handle, uri, false);
Expand All @@ -85,15 +88,19 @@ public Image getImage(ModuleHandle handle, String uri) {
* @param handle
* @param uri
* @param refresh
* @return
* @return Return the image
*/
public Image getImage(ModuleHandle handle, String uri, boolean refresh) {
Image image = null;
URL url = null;

try {
url = generateURL(handle, uri);
image = getImageFromURL(url, refresh);
if (uri.contains(DATA_PROTOCOL)) {
image = getEmbeddedImageDataURL(uri, refresh);
} else {
url = generateURL(handle, uri);
image = getImageFromURL(url, refresh);
}
} catch (Exception e) {
if (url != null && !invalidUrlList.contains(url.toString())) {
invalidUrlList.add(url.toString());
Expand All @@ -107,7 +114,9 @@ private Image getImageFromURL(URL url, boolean refresh) throws IOException {
return null;
}
String key = url.toString();
Image image = getImageRegistry().get(key);
Image image = null;

image = getImageRegistry().get(key);
if (image == null) {
image = loadImage(url);
}
Expand All @@ -124,9 +133,10 @@ private Image getImageFromURL(URL url, boolean refresh) throws IOException {
/**
* Gets the image by the given URI
*
* @param uri the url of the image file
* @param uri the uri of the image file
* @param refresh mark if refresh necessary
*
* @return Returns the image,or null if the url is invalid or the file format is
* @return Returns the image or null if the uri is invalid or the file format is
* unsupported.
*/
public Image getImage(String uri, boolean refresh) {
Expand All @@ -146,9 +156,10 @@ public Image getImage(String uri) {
/**
* Gets the embedded image
*
* @param embeddedImage the embedded image data
* @param handle handel of the design
* @param name name the image
*
* @return Returns the image,or null if the embedded image doesn't exist.
* @return Returns the image or null if the embedded image doesn't exist.
*/
public Image getEmbeddedImage(ModuleHandle handle, String name) {
String key = generateKey(handle, name);
Expand All @@ -169,7 +180,7 @@ public Image getEmbeddedImage(ModuleHandle handle, String name) {
// convert svg image to JPEG image bytes
JPEGTranscoder transcoder = new JPEGTranscoder();
// set the transcoding hints
transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, new Float(.8));
transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, .8f);
// create the transcoder input
TranscoderInput input = new TranscoderInput(
new ByteArrayInputStream(embeddedImage.getData(handle.getModule())));
Expand Down Expand Up @@ -228,6 +239,93 @@ public Image getEmbeddedImage(ModuleHandle handle, String name) {
return image;
}

/**
* Get the embedded image of the data URL
*
* @param url data URL of the image
* @param refresh refresh the image data or use image cache
* @return Return the embedded image
* @throws IOException
*/
public Image getEmbeddedImageDataURL(String url, boolean refresh) throws IOException {
if ((url == null) || (!refresh && invalidUrlList.contains(url))) {
return null;
}
String key = url;
Image image = null;
if (!refresh) {
image = getImageRegistry().get(key);
if (image != null) {
return image;
}
} else {
removeCachedImage(key);
}
InputStream in = null;
String[] imageDataArray = key.split(";base64,");
String imageDataBase64 = imageDataArray[1];
Decoder decoder = java.util.Base64.getDecoder();

try {
if (url.toLowerCase().contains("svg+xml")) //$NON-NLS-1$
{
// convert svg image to JPEG image bytes
JPEGTranscoder transcoder = new JPEGTranscoder();
// set the transcoding hints
transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, .8f);
// create the transcoder input
String svgURI = url;
TranscoderInput input = new TranscoderInput(svgURI);
// create the transcoder output
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
TranscoderOutput output = new TranscoderOutput(ostream);
try {
transcoder.transcode(input, output);
} catch (TranscoderException e) {
}
// flush the stream
ostream.flush();
// use the outputstream as Image input stream.
in = new ByteArrayInputStream(ostream.toByteArray());
} else {
in = new ByteArrayInputStream(decoder.decode(imageDataBase64));
}
ImageData[] datas = new ImageLoader().load(in);
if (datas != null && datas.length != 0) {
ImageData cur;
int index = 0;
for (int i = 0; i < datas.length; i++) {
ImageData temp = datas[i];
if (temp.width * temp.height > datas[index].width * datas[index].height) {
index = i;
}
}
cur = datas[index];
image = new Image(null, cur);
}
} catch (IOException e) {
throw e;
} catch (Exception ee) {
// do nothing
} finally {
if (in != null) {
in.close();
}
}
if (image != null) {
getImageRegistry().put(key, image);
}

if (image == null) {
if (!invalidUrlList.contains(url)) {
invalidUrlList.add(url);
}
} else {
invalidUrlList.remove(url);
}
return image;
}

/**
* Remove cached image from map
*
Expand All @@ -243,7 +341,8 @@ public void removeCachedImage(String key) {
/**
* Loads the image into the image registry by the given URI
*
* @param uri the URI of the image to load
* @param designHandle handle of report design
* @param uri the URI of the image to load
* @return Returns the image if it loaded correctly
* @throws IOException
*/
Expand All @@ -258,9 +357,9 @@ public Image loadImage(ModuleHandle designHandle, String uri) throws IOException
/**
* Reload the image, refresh the cache.
*
* @param designHandle
* @param uri
* @return
* @param designHandle handle of report design
* @param uri the URI of the image to load
* @return Reload the image
* @throws IOException
*/
public Image rloadImage(ModuleHandle designHandle, String uri) throws IOException {
Expand All @@ -271,18 +370,32 @@ public Image rloadImage(ModuleHandle designHandle, String uri) throws IOExceptio
return loadImage(url, true);
}

/**
* Load the image based on URI
*
* @param uri the image URI
* @return Return the loaded image
* @throws IOException
*/
public Image loadImage(String uri) throws IOException {
return loadImage(null, uri);
}

/**
* Load the image based on URI
*
* @param url the image URL
* @return Return the loaded image
* @throws IOException
*/
public Image loadImage(URL url) throws IOException {
return loadImage(url, false);
}

/**
* @param url
* @param reload
* @return
* @param url the image URL
* @param reload image should be refreshed or used from cache
* @return Return the loaded image
* @throws IOException
*/
public Image loadImage(URL url, boolean reload) throws IOException {
Expand All @@ -304,7 +417,7 @@ public Image loadImage(URL url, boolean reload) throws IOException {
// convert svg image to JPEG image bytes
JPEGTranscoder transcoder = new JPEGTranscoder();
// set the transcoding hints
transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, new Float(.8));
transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, .8f);
// create the transcoder input
String svgURI = url.toString();
TranscoderInput input = new TranscoderInput(svgURI);
Expand All @@ -325,10 +438,6 @@ public Image loadImage(URL url, boolean reload) throws IOException {
ImageData[] datas = new ImageLoader().load(in);
if (datas != null && datas.length != 0) {
ImageData cur;
// if (datas.length == 1)
// {
// cur = datas[0];
// }
int index = 0;
for (int i = 0; i < datas.length; i++) {
ImageData temp = datas[i];
Expand Down Expand Up @@ -358,12 +467,19 @@ private ImageRegistry getImageRegistry() {
return CorePlugin.getDefault().getImageRegistry();
}

/**
* Generate the image URL
*
* @param designHandle
* @param uri of the image
* @return Return the URL of the image
* @throws MalformedURLException
*/
public URL generateURL(ModuleHandle designHandle, String uri) throws MalformedURLException {
try {
return new URL(uri);
} catch (MalformedURLException e) {
String path = URIUtil.getLocalPath(uri);

if (designHandle == null) {
designHandle = SessionHandleAdapter.getInstance().getReportDesignHandle();
}
Expand All @@ -379,7 +495,7 @@ public URL generateURL(ModuleHandle designHandle, String uri) throws MalformedUR
/**
* Generate hash key.
*
* @param reportDesignHandle Moudle handle
* @param reportDesignHandle Module handle
* @param name Name
* @return key string
*/
Expand All @@ -390,9 +506,9 @@ public String generateKey(ModuleHandle reportDesignHandle, String name) {
/**
* Reload the URI image, refresh the cache.
*
* @param moduleHandel
* @param uri
* @return
* @param moduleHandel Module handle
* @param uri uri of the image
* @return Return the reloaded image
*/
public Image reloadURIImage(ModuleHandle moduleHandel, String uri) {
URL url = createURIURL(uri);
Expand All @@ -417,6 +533,12 @@ public Image reloadURIImage(ModuleHandle moduleHandel, String uri) {
return image;
}

/**
* Create the URL based on URI
*
* @param uri uri string
* @return Return the URL based on URI
*/
public URL createURIURL(String uri) {
URL url = null;
try {
Expand All @@ -440,9 +562,9 @@ public URL createURIURL(String uri) {
/**
* Get image from URI
*
* @param moduleHandel
* @param uri
* @return
* @param moduleHandel Module handle
* @param uri URI of the image
* @return Return the image based on URI
*/
// bugzilla 245641
public Image getURIImage(ModuleHandle moduleHandel, String uri) {
Expand All @@ -458,6 +580,11 @@ public Image getURIImage(ModuleHandle moduleHandel, String uri) {
return image;
}

/**
* Set the URI root path
*
* @param rootPath Root path of the URI
*/
public void setURIRootPath(String rootPath) {
this.resourcesRootPath = rootPath;
}
Expand Down
Loading

0 comments on commit 85a0fb5

Please sign in to comment.