Grab image data from URL via proxy and convert to base64 - image

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.

Related

How to set content type using Azure Java azure-storage-blob SDK

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);

XSL FO get image from server

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.

Why base64 image is big ? xamarin forms

I am facing one error sometimes, when I try get a picture from user gallery.
I get the picture in a Stream object, convert it to a base64 and I send it using a post function.
Sometimes The program says that the image path is big and, because of that, its not possible send the url.
I heard that its cause the image size but I am not sure about it...
Does someone know what really causes a Big base64 string? How can I solve that?
You could follow something similar to this:
http://jamessdixon.wordpress.com/2013/10/01/handling-images-in-webapi/
Maybe you need make some change in your web api like this:
[HttpPost]
public HttpResponseMessage UploadImage(int ID)
{
var result = new HttpResponseMessage(HttpStatusCode.OK);
if (Request.Content.IsMimeMultipartContent())
{
Request.Content.LoadIntoBufferAsync().Wait();
Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider()).ContinueWith((task) =>
{
MultipartMemoryStreamProvider provider = task.Result;
foreach (HttpContent content in provider.Contents)
{
Stream stream = content.ReadAsStreamAsync().Result;
Image image = Image.FromStream(stream);
var testName = content.Headers.ContentDisposition.Name;
String filePath = HostingEnvironment.MapPath("~/Content/");
String fullPath = Path.Combine(filePath, ID.ToString()+".jpg");
image.Save(fullPath);
}
});
return result;
}
else
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
}
}
After making sure your api web works well you should change from Stream to byte[]
In your Xamarin code try this:
public async Task PostItem(String Controller, String Method, int ID, byte[] item)
{
using (var client = CreateClient ()) {
var da = new ByteArrayContent(item);
try{
var multi = new MultipartContent();
multi.Add(da);
var response = await client.PostAsync (Controller + "/" +Method + "/?ID=" +ID, multi);
}catch(Exception ex)
{
Console.Write(ex.Message);
}
}
}
For more infomation see MultipartContent class documentation

Mixing JSON data and image content in a single HTTP response

Is it possible to include multiple response types in a single HTTP response? For example, JSON data as well as an image.
Hey It is not possible to set multiple MIME TYPE to HTTPResponse. But what you can do is, you can set the content type as application/json. And using json you can send the image using BASEEncoder.
public static String encodeToString(BufferedImage image, String type) {
String imageString = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(image, type, bos);
byte[] imageBytes = bos.toByteArray();
BASE64Encoder encoder = new BASE64Encoder();
imageString = encoder.encode(imageBytes);
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
return imageString;
}
No. I think one generally would send the URL of image in json, and use javascript to update the "src" attribute of "img" element

Retrieve image from my sql in GWT

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.

Resources