so far i m trying
BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
but its give an error does don't support ImageIO in Apps engine.
The Image service Java API lets you apply transformations to images, The app prepares an Image object with the image data to transform, and a Transform object with instructions on how to transform the image, Check this link
byte[] oldImageData; // ...
ImagesService imagesService = ImagesServiceFactory.getImagesService();
Image oldImage = ImagesServiceFactory.makeImage(oldImageData);
Transform resize = ImagesServiceFactory.makeResize(200, 300);
Image newImage = imagesService.applyTransform(resize, oldImage);
byte[] newImageData = newImage.getImageData();
App Engine works in a sandbox, thus a lot of Java libraries are not accessible. For details, see this link [1].
The workaround provided in the other answer let's your buffer an image but it doesn't directly answer your question why you got the ImageIO error.
[1] - JRE whitelist for Google App Engine - https://cloud.google.com/appengine/docs/java/jrewhitelist
Related
I've encountered this strange issue while trying to transfer images from my Java webserver to my Amazon S3 bucket. I am developing a mobile application for both Android and iOS (with Swift), which allows users to upload images from their device to the server.
The images (Bitmaps for Android, and UIImage for iOS) are both converted to Base 64 before being sent to my webserver (made in Java to conform to HTTP/1.1 standards). The data arrives to the server intact (meaning by printing the base 64 before it is sent, and after it arrives to the server, they are identical). From there I decode the String into a byte array. I have isolated the issue to have something to do with the actual sending process to the Amazon S3 bucket. Take the following snippet for example:
//image is a byte array, and imageid a String
InputStream is = new ByteArrayInputStream(image);
AmazonS3 s3 = new AmazonS3Client();
ObjectMetadata meta = new ObjectMetadata();
meta.setContentType("image/jpeg");
meta.setContentLength(image.length);
s3.putObject(new PutObjectRequest("bucket", "images/" + imageid + ".jpg", is, meta));
This code works fine for Android, where the images upload at 1080x1080 without an issue. However, when I try to upload an image from iPhone, the resolution becomes 1080x1081. Confused by this, I decided to try saving the image locally as well as send it to the server using ImageIO. Strangely enough, using:
BufferedImage img = ImageIO.read(new ByteArrayInputStream(image));
File f = new File("image.jpg"); //Removed file creation for brevity
ImageIO.write(img, "jpg", f);
When I used the "identify" command from Imagick on the local image, the output is:
image.jpg JPEG 1080x1080 1080x1080+0+0 8-bit DirectClass 53.4KB 0.000u 0:00.000
However when I transfer the image from the S3 bucket and do the same thing, I get:
image2.jpg JPEG 1080x1081 1080x1081+0+0 8-bit DirectClass 56.2KB 0.000u 0:00.000
Again, this only occurs with uploads from iOS. The image itself is still valid and opens without an issue. For example:
Face Down Camera Image
(Picture was taken while the camera was facing down, hence the dark image)
I suspect the issue may have something to do with differences in how the images are encoded into Base 64. I use the Bouncycastle library to do the encoding on Android, as well as the decoding on the webserver, and use an NSData function in swift as described below:
let imageData = UIImageJPEGRepresentation(normImg, 0.4)
let base64 = NSString(data: imageData!.base64EncodedDataWithOptions(NSDataBase64EncodingOptions(rawValue: 0)), encoding: NSUTF8StringEncoding) as! String
What confuses me the most is how ~3KB of data (which makes sense for 1080 extra pixels at 3 bytes per RGB pixel) seems to just be appearing out of nowhere, and why it seems to be isolated to iOS.
Hopefully I was clear enough with my question and the debugging I have done to provide as much information as possible. If you need any more information, please let me know!
Edit: Just ran a test and uploaded a 1080x1080 image by command line to the S3 bucket. It also adds the extra pixels.
Edit2: Decided to change how the file uploading process worked. It is no longer being converted to base 64, and the NSData of the UIImage is being converted into a byte (UInt8) array and uploaded. The still leads to the same result of having the extra pixel, which rules out my original speculation that it had something to do with the base64 encoding. Android still seems to function properly on the other hand, which leaves me to believe that the binary data of the image is not completely valid for whatever reason. I believe the EXIF data is formatted differently between Android and iOS, though I don't know what would cause this.
I am trying to convert an image (url below) using two libraries (thumbnailator and imgscalr. My code works on most of the images except a few which after conversion have a pink/reddish tint.
I am trying to understand the cause and would welcome any recommendation.
Note - Image type of this image is 5 i.e BufferedImage.TYPE_3BYTE_BGR and i am using Java 7
Using Thumbnailator
Thumbnails.of(fromDir.listFiles())
.size(thumbnailWidth, thumbnailHeight)
.toFiles(Rename.SUFFIX_HYPHEN_THUMBNAIL);
Using imgscalr
BufferedImage bufferedImage = ImageIO.read(file);
final BufferedImage jpgImage;
LOG.debug("image type is =[{}] ", bufferedImage.getType());
BufferedImage scaledImg = Scalr.resize(bufferedImage, Method.ULTRA_QUALITY, thumbnailWidth, thumbnailHeight, Scalr.OP_ANTIALIAS);
File thumbnailFile = new File(fromDirPath + "/" + getFileName(file.getName()) +THUMBNAIL_KEYWORD + ".png");
ImageIO.write(scaledImg, getFileExtension(file.getName()), thumbnailFile);
bufferedImage.flush();
scaledImg.flush();
I get this question a lot (author of imgscalr) -- the problem is almost always that you are reading/writing out different file formats and the ALPHA channel is causing one of your color channels (R/G/B) to be culled from the resulting file.
For example, if you read in a file that was ARGB (4 channel) and wrote it out as a JPG (3 channel) - unless you purposefully manipulate the image types yourself and render the old image to the new one directly, you will get a file with a "ARG" channels... or more specifically, just Red and Green - no Blue.
PNG supports an alpha channel and JPG does not, so be aware of that.
The way to fix this is to purposefully create appropriate BufferedImage's of the right type (RGB, ARGB, etc.) and using the destImage.getGraphics() call to render one image to the other before writing it out to disk and re-encoding it.
Sun and Oracle have NEVER made the ImageIO libraries smart enough to detect the unsupported channels when writing to differing file types, so this behavior happens all the time :(
Hope that helps!
The following piece of code resolved my issue:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Thumbnails.of(new ByteArrayInputStream(imageByteArray))
.outputFormat("jpg")
.size(200, 200)
.toOutputStream(outputStream);
return baos.toByteArray();
I am using Thumbnailator and the code was posted here: https://github.com/coobird/thumbnailator/issues/23
** I am developing a Java Application for reading(decoding) QR Codes with out using camera in the laptop. I am using the ZXING JAR for the generation of QR Code.**
I am doing some manipulation for that QR Code. Now, I wanted to check whether the QR Code is fine or not with out using camera.
Is there any way it can be done?
ZXing has a JavaSE module which provides the crucial BufferedImageLuminanceSource for decoding a regular Java BufferedImage.
The bare minimum, extracted from ZXing's JavaSE DecodeThread:
BufferedImage image = ...
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = new MultiFormatReader().decode(bitmap);
If decode() doesn't throw an exception, ZXing was able to decode the barcode (and you can check the contents of the bar code).
http://zxing.org/w/docs/javadoc/com/google/zxing/Reader.html#decode(com.google.zxing.BinaryBitmap, java.util.Map)
You can configure the MultiFormatReader, e.g. to only parse QR codes, by using the decode(BinaryBitmap, Map<DecodeHintType,?> hints) overload, allowing you to specify any number of decoding hints. Alternatively, if you really only want QR codes, use a QRCodeReader instead of MultiFormatReader.
So I'm making an application to store shortcuts to all the user's favorite applications, acting kind of like a hub. I can have support for actual files and I have a .lnk parser for shortcuts. I thought it would be pretty good for the application to support Internet shortcuts, too. This is what I'm doing:
Suppose I'm trying to get Google's icon (http://www.google.com/favicon.ico).
I start out by getting rid of the extra pages (e.g. www.google.com/anotherpage would become www.google.com.
Then, I use ImageIO.read(java.net.URL) to get the Image.
The problem is that ImageIO never returns an Image when I call this method:
String trimmed = getBaseURL(page); //This removes the extra pages
Image icon = null;
try {
String fullURLString = trimmed + "/favicon.ico";
URL faviconURL = new URL(fullURLString);
icon = ImageIO.read(faviconURL);
} catch (IOException e) {
e.printStackTrace();
}
return icon;
Now I have two questions:
Does Java support the ICO format even though it is from Microsoft?
Why does ImageIO fail to read from the URL?
Thank you in advance!
Try Image4J.
As this quick Scala REPL session shows (paste-able as Java code):
> net.sf.image4j.codec.ico.ICODecoder.read(new java.net.URL("http://www.google.com/favicon.ico").openStream())
res1: java.util.List[java.awt.image.BufferedImage] = [BufferedImage#65712a80: type = 2 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=ff000000 IntegerInterleavedRaster: width = 16 height = 16 #Bands = 4 xOff = 0 yOff = 0 dataOffset[0] 0]
UPDATE
To answer your questions: Does Java support ICO? Doesn't seem like it:
> javax.imageio.ImageIO.read(new java.net.URL("http://www.google.com/favicon.ico"))
java.lang.IllegalArgumentException: Empty region!
Why does ImageIO fail to read from the URL? Well, the URL itself seems to work for me, so you may have a proxy/firewall issue, or it could be the problem above.
Old post, but for future reference:
I've written a plugin for ImageIO that adds support for .ICO (MS Windows Icon) and .CUR (MS Windows Cursor) formats.
You can get it from GitHub here: https://github.com/haraldk/TwelveMonkeys/
After you have installed the plugin, you should be able to read the icon, using the code in the original post without any modifications.
You don't need ImageIO for this. Just copy the bytes, same as for any other static resource.
There is Apache Commons Imaging for reading ico files and others: https://commons.apache.org/proper/commons-imaging/index.html
Reading an ico file works like this:
List<BufferedImage> images = org.apache.commons.imaging.Imaging.getAllBufferedImages(yourIcoFile);
In your case you have to download it first, I guess.
hi
I am fetching the image from the web page using Jtidy in java.
This is the my code:
URL url = new URL("http://www.yahoo.com");
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
InputStream in=in = conn.getInputStream();
Document doc=new Tidy().parseDOM(in, null);
NodeList img = doc.getElementsByTagName("img");
list.add(img.item(0).getAttributes().getNamedItem("src").getNodeValue());
It is working properply, but I am getting some large images. I want to set height and width 16*16.
Please help me: how to set the size while fetching the image.
When fetching an image from a web server you can't specify which size you want the image to be in. You'll always get the "original" size of the image.
You will have to resize the image yourself, after fetching it.
Related questions (with good answers):
Resize Image files
How can I resize an image using Java?
Resize image while keeping aspect ratio in Java
I guess you want to reduce the amount of downloaded data? If so, you are out of luck because you can't force the remote server to do the scaling for you. The general case is, that it just sends you the file (aka resource) you requested.
What you can do is scale the image after it was downloaded, which has been discussed in detail here on SO.