Im using FOP version 2.1. I have a xsl fo template where i want to show images:
<xsl:variable name="ImagePath" select="defaultImageUrl"/>
<fo:external-graphic src="{$ImagePath}" content-width="scale-down-to-fit" width="100%"/>
Some images have a webadress like so:
https://upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Tulipa_biflora_UME.jpg/800px-Tulipa_biflora_UME.jpg
But other images come from my webserver from address like:
https://localhost:4200/api/download/image/?fixedPrice=true&productId=1329&fileId=1304
This responds to endpoint:
public ResponseEntity<byte[]> getFileAsResponseEntity(#RequestParam boolean fixedPrice, #RequestParam long productId, #RequestParam long fileId) throws IOException, SQLException {
HttpHeaders headers = new HttpHeaders();
FileDownload fileDownload = productService.getProductFile(productId, fileId, fixedPrice);
headers.setCacheControl(CacheControl.noCache().getHeaderValue());
String n = fileDownload.getFileName().toLowerCase();
if (fileDownload.getFileTypeEnum().equals(FileTypeEnum.PICTURE) && (n.contains(".jpeg") || n.contains("jpg"))) {
headers.setContentType(MediaType.IMAGE_JPEG);
} else if (fileDownload.getFileTypeEnum().equals(FileTypeEnum.PICTURE) && (n.contains(".png"))) {
headers.setContentType(MediaType.IMAGE_PNG);
} else if (fileDownload.getFileTypeEnum().equals(FileTypeEnum.PICTURE) && (n.contains(".gif"))) {
headers.setContentType(MediaType.IMAGE_GIF);
}
return new ResponseEntity<>(fileDownload.getByteArray(), headers, HttpStatus.OK);
}
Is there a way for fo:external-graphic to accept these 2 different urls? Or is there something additional i need to do for it to work, since currently when the image comes from the webserver, the the resulting pdf file does not have the image in it, only a white space.
EDIT:
Here is the code that should make the XML to XSL to PDF:
byte[] xsl = IOUtils.toByteArray(this.getClass().getResourceAsStream("/browserDocument.xsl"));
byte[] xml = getBrowserDocument(filter, clientId, representId, ecatMain, showImage, language);
InputStream inStr = this.getClass().getResourceAsStream("/fop.xml");
FopFactory fopFactory = FopFactory.newInstance(new java.net.URI("."), inStr);
ByteArrayOutputStream out = new ByteArrayOutputStream();
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);
javax.xml.transform.Source xsltSrc = new StreamSource(new ByteArrayInputStream(xsl));
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(xsltSrc);
String xmlStr = new String(xml, "UTF-8");
xmlStr = xmlStr.replaceAll("<", "<");
xmlStr = xmlStr.replaceAll(">", ">");
javax.xml.transform.Source src = new StreamSource(new ByteArrayInputStream(xmlStr.getBytes("UTF-8")));
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
return out.toByteArray();
I keep getting error message in the log files:
2019-01-30 16:07:48.300 ERROR 8424 --- [https-jsse-nio-8087-exec-3] org.apache.fop.apps.FOUserAgent : Image not found. URI: https://localhost:4200/api/efront/secure/download/product/image/?fixedPrice=false&productId=2823&fileId=1756. (No context info available)
It seems like it is calling the URL, but it is not getting the actual image from it. Maybe some issue with the image headers or the FOUseragent is getting blocked?
Well, implementing all above possible logic and seeing your code, I think URIResolver would help getting out of this as below:
Add it to your code : fopFactory.setURIResolver(new ResolveURIForWebServer());
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
public class ResolveURIForWebServer implements URIResolver {
#Override
public Source resolve(String href, String baseURI) throws TransformerException {
Source source = null;
try {
// CONVERT IMAGE TO INPUTSTREAM
source = new StreamSource(InputStream);
} catch (Exception e) {
} finally {
}
return source;
}
}
Hope it helps.
Related
My code looks like:
try {
MultipartFile file = uploadFileInfo.getUploadFile();
InputStream inputStream = new BufferedInputStream(file.getInputStream());
BlobProperties props = blockBlobClient.getProperties();
blockBlobClient.upload(inputStream, file.getBytes().length);
} catch (IOException e) {
log.error("Unable to upload blob!", e);
return baseResp;
}
However the file contentType is application/octet-stream, and I need to set it to "image/jpg". How can I do this with the Java SDK?
To upload a blob and set it's content type, please use the following method: BlockBlobClient.uploadWithResponse. Here's the sample code (taken from the same link):
BlobHttpHeaders headers = new BlobHttpHeaders()
.setContentType("image/jpg");
Map<String, String> metadata = Collections.singletonMap("metadata", "value");
byte[] md5 = MessageDigest.getInstance("MD5").digest("data".getBytes(StandardCharsets.UTF_8));
BlobRequestConditions requestConditions = new BlobRequestConditions();
Context context = new Context("key", "value");
client.uploadWithResponse(data, length, headers, metadata, AccessTier.HOT, md5,
requestConditions, timeout, context);
The upload method does not provide this option, you need to use the uploadWithResponse method, which allows you to specify this and many other parameters. Here's an example:
ParallelTransferOptions parallelTransferOptions = new ParallelTransferOptions();
BlobHttpHeaders headers = new BlobHttpHeaders().setContentType(MediaType.IMAGE_JPEG_VALUE);
Map<String, String> metadata = Collections.singletonMap("metadata", "value");
BlobRequestConditions requestConditions = new BlobRequestConditions();
Context context = new Context("key", "value");
Duration timeout = Duration.ofSeconds(60);
blobClient.uploadWithResponse(inputStream, size, parallelTransferOptions, headers, metadata, AccessTier.HOT, requestConditions, timeout, context);
I need your help:
I have the following method
#Path("/download")
public class FileDownloadService {
#GET
public Response downloadFile(#QueryParam("filenet_id") String filenet_id, #QueryParam("version") String version) {
...
Document document = (Document) cmisObject;
return Response.ok(document, MediaType.APPLICATION_OCTET_STREAM).build();
}
and I want to get the document throught HTTP GET, I tried to write this code but I don't know how to get it, "output" don't conatains it:
URIBuilder builder = new URIBuilder();
builder.setScheme("http").setHost("localhost:8080").setPath("/filenetintegration/rest/download")
.setParameter("filenet_id", filenet_id)
.setParameter("version", version+".0");
URI uri = builder.build();
HttpGet httpget = new HttpGet(uri);
System.out.println(httpget.getURI());
HttpURLConnection urlConnection = (HttpURLConnection) new URL(uri.toString()).openConnection();
urlConnection.connect();
BufferedReader br = new BufferedReader(new InputStreamReader((urlConnection.getInputStream())));
String output;
while ((output = br.readLine()) != null) {
System.out.println(output);
}
Edit:
maybe the problem is on this line, it don't put the document inside the response:
return Response.ok(document, MediaType.APPLICATION_OCTET_STREAM).build();
You need something like this on the server side:
Document document = (Document) cmisObject;
ContentStream contentStream = document.getContentStream();
final InputStream stream = contentStream.getStream();
StreamingOutput output = (OutputStream out) -> {
try {
int b;
byte[] buffer = new byte[64*1024];
while ((b = stream.read(buffer)) > -1) {
out.write(buffer, 0, b);
}
} finally {
try {
stream.close();
} catch (IOException ioe) {}
}
};
return Response.ok(output, contentStream.getMimeType()).build();
I've got a question related to grabbing an image from a URL via proxy and converting it to base64.
Is there a simple way of doing this like the below jsoup method?
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("myproxyurl", 8080))
Document doc = Jsoup.connect("mytargeturl").proxy(proxy).get()
Elements headline = doc?.getElementsByClass("myHTMLclass")
I am looking to do this in Groovy/Java (preferably Groovy).
So far I got here:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("myproxy", 8080))
URL url = new URL("https://maps.googleapis.com/maps/api/staticmap?size=600x400&markers=size:large%7Ccolor:yellow%7Clabel:A%7CNew%20York")
def image = url.openConnection(proxy).getContent()
println(image)
But I'm getting sun.awt.image.URLImageSource#26d9b808 as an output in the console
Can anyone help? The image in question is this one:
Just to be clear, I want to grab the above image (actual image) from the above-mentioned URL and convert it to base64 string.
Just do:
// By default this won't use a proxy, but if you pass one in, it will!
String toBase64(URL url, Proxy proxy = Proxy.NO_PROXY) {
url.openConnection(proxy).inputStream.withCloseable {
it.bytes.encodeBase64()
}
}
URL url = new URL("https://maps.googleapis.com/maps/api/staticmap?size=600x400&markers=size:large%7Ccolor:yellow%7Clabel:A%7CNew%20York")
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("myproxyurl", 8080));
String encoded = toBase64(url, proxy)
Not sure about proxy settings, but if you want to convert image into base64 with java, so that you can do with below code.
public class ChangeBase {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String encodstring = encodeFileToBase64("http://imageurl");
System.out.println(encodstring);
}
private static byte[] getByteFromImage(String urlStr) throws Exception {
URL url = new URL(urlStr);
BufferedImage image = ImageIO.read(url);
// get DataBufferBytes from Raster
WritableRaster raster = image.getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
return data.getData();
}
private static String encodeFileToBase64(String url) {
String encodedString = null;
try {
byte[] bytes = getByteFromImage(url);
encodedString = new String(Base64.getEncoder().encode(bytes), "UTF-8");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return encodedString;
}
}
Note: I used above code for image stored in my drive, same thing you can try with image from url, suggested one is create byte to file from url and pass same to encodeFiletoBase64 method, don't save file locally on system.
I have a solution for copying rich text content from one document to MIME in another document. See http://per.lausten.dk/blog/2012/12/xpages-dynamically-updating-rich-text-content-in-a-ckeditor.html. I use this in an application as a way for the user to insert content templates in a new document and have the content appear on-the-fly in the CKEditor.
The problem is that inline images are not included in the copying - only a reference to temporary storage of the images. This means that the images are only visible for the current user in the current session. So not very useful.
How can I include images?
Update October 4, 2013:
I'm still looking for a solution to this.
I finally got it work. It was much more simple and did not even involve MIME. The trick was to modify the image tags in the working HTML to include the base64 encoded image so that the src tag could use this format (here shown with a gif as example):
src="data:image/gif;base64,<base64 encoded image>"
I already had the code necessary to get the HTML from the rich text field (see my blog post already mentioned in my question). So all I needed was to replace the image src tags with the correct src format including the base64 encoded image.
The following code gets the HTML and goes through each of the included images and modifies the src tag:
String html = this.document.getValue(fieldName).toString();
if (null != html) {
final List<FileRowData> fileRowDataList = document.getEmbeddedImagesList(fieldName);
if (null != fileRowDataList) {
final Matcher matcher = imgRegExp.matcher(html);
while (matcher.find()) {
String src = matcher.group();
final String srcToken = "src=\"";
final int x = src.indexOf(srcToken);
final int y = src.indexOf("\"", x + srcToken.length());
final String srcText = src.substring(x + srcToken.length(), y);
for (FileRowData fileRowData : fileRowDataList) {
final String srcImage = fileRowData.getHref();
final String cidImage = ((AttachmentValueHolder) fileRowData).getCID();
final String typeImage = ((AttachmentValueHolder) fileRowData).getType();
final String persistentName = ((AttachmentValueHolder) fileRowData).getPersistentName();
// Add base 64 image inline (src="data:image/gif;base64,<name>")
if (srcText.endsWith(srcImage)) {
final String newSrc = src.replace(srcText, "data:" + typeImage + ";base64," + getBase64(persistentName));
html = html.replace(src, newSrc);
}
}
}
}
}
Here is the getBase64() method that base64 encodes an image:
private String getBase64(final String fileName) {
String returnText = "";
try {
BASE64Encoder base64Enc = new BASE64Encoder();
ByteArrayOutputStream output = new ByteArrayOutputStream();
base64Enc.encode(this.getEmbeddedImageStream(fileName), output);
returnText = output.toString();
} catch (NotesException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return returnText;
}
Some of the code is from the emailBean by Tony McGuckin.
Can you get a handle to the inline image by the DominoDocument.AttachmentValueHolder, see http://public.dhe.ibm.com/software/dw/lotus/Domino-Designer/JavaDocs/XPagesExtAPI/8.5.2/com/ibm/xsp/model/domino/wrapped/DominoDocument.AttachmentValueHolder.html
I blogged about attachments inside notes documents, see http://www.domino-weblog.nl/weblogs/Domino_Blog.nsf/dx/xpages-tip-get-easily-access-to-your-attachments-in-java.htm
Gruesome hack (you need to sort out authentication and server names)
The SSJS (getting the source from a view)
var unid = curRow.getUniversalID();
var body = getComponent("body1");
var magic = new demo.HTMLMagic();
magic.doMagic(database, unid, body);
The Java
package demo;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import net.htmlparser.jericho.Attribute;
import net.htmlparser.jericho.Attributes;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.OutputDocument;
import net.htmlparser.jericho.Source;
import net.htmlparser.jericho.StartTag;
import lotus.domino.Database;
import lotus.domino.NotesException;
import com.ibm.misc.BASE64Encoder;
import com.ibm.xsp.component.xp.XspInputRichText;
import com.ibm.xsp.http.IMimeMultipart;
import com.ibm.xsp.model.domino.wrapped.DominoRichTextItem;
public class HTMLMagic {
private HttpClient httpClient = null;
private HttpHost httpHost = null;
//TODO: that needs to be resolved smarter
private static final String HOSTNAME = "localhost";
public void doMagic(final Database database, final String unid, final XspInputRichText body) throws NotesException,
ClientProtocolException, IOException {
final String docURL = "http://" + HOSTNAME + "/__" + database.getReplicaID() + ".nsf/0/" + unid + "/Body?OpenField";
final String fixedHTML = this.fixHTML(docURL);
IMimeMultipart result = DominoRichTextItem.convertToMime("-- copied text--<br />" + fixedHTML);
body.setValue(result);
}
private String fixHTML(final String rawHTMLstring) throws ClientProtocolException, IOException {
HttpHost target = this.getHttpHost();
HttpClient client = this.getHttpClient();
HttpGet get = new HttpGet(rawHTMLstring);
HttpResponse response = client.execute(target, get);
InputStream data = response.getEntity().getContent();
Source rawHTML = new Source(data);
OutputDocument outputDocument = new OutputDocument(rawHTML);
StringBuilder sb = new StringBuilder();
String tagName = HTMLElementName.IMG;
String attName = "src";
List<StartTag> links = rawHTML.getAllStartTags(tagName);
for (StartTag onelink : links) {
String href = onelink.getAttributeValue(attName);
if (href != null) {
String replace = this.urltoData(href);
if (replace != null) {
sb.setLength(0);
sb.append("<");
sb.append(tagName);
sb.append(" ");
sb.append(attName);
sb.append("=\"");
sb.append(replace);
sb.append("\"");
Attributes atts = onelink.getAttributes();
if (!atts.isEmpty()) {
for (int i = 0; i < atts.size(); i++) {
Attribute att = atts.get(i);
if (!att.getName().equals(attName)) {
sb.append(" ");
sb.append(att.getName());
sb.append("=\"");
sb.append(att.getValue());
sb.append("\" ");
}
}
}
sb.append(">");
outputDocument.replace(onelink, sb.toString());
}
}
}
return outputDocument.toString();
}
private HttpClient getHttpClient() {
if (this.httpClient == null) {
// general setup
SchemeRegistry supportedSchemes = new SchemeRegistry();
// Register the "http" protocol scheme, it is required
// by the default operator to look up socket factories.
supportedSchemes.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// prepare parameters
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "UTF-8");
HttpProtocolParams.setUseExpectContinue(params, true);
ClientConnectionManager connMgr = new ThreadSafeClientConnManager(params, supportedSchemes);
this.httpClient = new DefaultHttpClient(connMgr, params);
}
return this.httpClient;
}
private HttpHost getHttpHost() {
if (this.httpHost == null) {
this.httpHost = new HttpHost(HOSTNAME, 80, "http");
}
return this.httpHost;
}
private String urltoData(final String href) throws ClientProtocolException, IOException {
StringBuilder sb = new StringBuilder();
sb.append("data:image/");
sb.append(href.substring(href.lastIndexOf("FieldElemFormat=") + 1));
sb.append(";base64,");
// Here go the Image data
HttpHost target = this.getHttpHost();
HttpClient client = this.getHttpClient();
HttpGet get = new HttpGet(href);
HttpResponse response = client.execute(target, get);
InputStream data = response.getEntity().getContent();
BASE64Encoder encoder = new BASE64Encoder();
OutputStream output = new ByteArrayOutputStream();
encoder.encode(data, output);
sb.append(output.toString());
output.close();
return sb.toString();
}
}
Would be curious if that works for you. The Notes client can't show inline HTML images
I am working on GWT RPC. I am facing a problem in retrieving image from my SQL.
Here is my code:
Base64 bas = new Base64();
// sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
UploadfileJpaController up = new UploadfileJpaController();
// this function returns the value in blob field in the form of byte array
byte[] b = up.findUploadfile(n);
String base64Contents = enc.encode(b).replaceAll("\\s+", "");
//String base64 = Base64Utils.toBase64(b);
base64Contents = "data:image/gif;base64,"+base64Contents;
return base64Contents;
But this is not working.. the image is not displayed. Please help :(
You should let a regular servlet take care of returning the image data, and not use GWT-RPC. The servlet should set the proper image/gif header and write the binary data to the response outputstream.
EDIT
This should look somewhat like this
public class FileDownloadServlet extends HttpServletv {
// This method is called by the servlet container to process a GET request.
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// Set content type
resp.setContentType("image/gif");
//Up to you!
byte[] binaryData = getDataFromDbase();
ByteArrayInputStream bis = new ByteArrayInputStream(binaryData);
OutputStream out = resp.getOutputStream();
// Copy the contents of the file to the output stream
byte[] buf = new byte[1024];
int count = 0;
while ((count = bis.read(buf)) >= 0) {
out.write(buf, 0, count);
}
bis.close();
out.close();
}
}
You url is going to be something like
http://server/application/image_servlet?id=123545 where you use the id parameter in the servlet to look up the image. And of course add the servlet to you web.xml. Good luck.