I have inputStream Object when i try to convert in bitmap it works but for some images it will return me null still, image is present.
InputStream responseInputStream = apiResponseModel
.getResponseInputStream();
if (responseInputStream != null) {
Bitmap bmp = BitmapFactory.decodeStream(responseInputStream);
imgProductProfile.setImageBitmap(bmp);
}
The image you are trying to decode may not be supported for decoding. Android supports only few image types for decoding. The supported format is listed here
http://developer.android.com/guide/appendix/media-formats.html. Try converting your image to other format like PNG , JPG and try decoding
Related
I have a Data-URL from an image file and have to pass it through to another function. Along this path from Data-URL to the BufferedImage it needs to be a byteArray.
my approach was the following:
String dataUrl;
byte[] imageData = dataUrl.getBytes();
// pass the byteArray along the path
// create BufferedImage from byteArray
BufferedImage inputImage = ImageIO.read(new ByteArrayInputStream(imageData));
// If the picture is null, then throw an unsupported image exception.
if (inputImage == null) {
throw new UnknownImageFormatException();
}
The problem is, it always throws the UnknownImageFormatException Exception, which means inputImage is null, which means, the ImageIO.read did not recognize the imagetype.
I've used ImageIO.getReaderFormatNames() to get the supported Filenames and got the following list:
Supported Formats:
jpg, BMP, bmp, JPG, jpeg, wbmp, png, JPEG, PNG, WBMP, GIF, gif
The dataURLs I try to pass are like: data:image/png;base64,... or data:image/jpg;base64,...
As far as I understand, those are in the supported filelist and therefor should be recognized.
What else could cause the inputImage to be null in this case? And more interesting, how do I solve it?
As the comments already said the image data is Base64 encoded. To retrieve the binary data you have to strip the type/encoding headers, then decode the Base64 content to binary data.
String encodingPrefix = "base64,";
int contentStartIndex = dataUrl.indexOf(encodingPrefix) + encodingPrefix.length();
byte[] imageData = Base64.decodeBase64(dataUrl.substring(contentStartIndex));
I use org.apache.commons.codec.binary.Base64 from apaches common-codec, other Base64 decoders should work as well.
The only one problem with RFC2397 string is its specification with everything before data but data: and , optional:
data:[<mediatype>][;base64],<data>
So pure Java 8 solution accounting this would be:
final int dataStartIndex = dataUrl.indexOf(",") + 1;
final String data = dataUrl.substring(dataStartIndex);
byte[] decoded = java.util.Base64.getDecoder().decode(data);
Of course dataStartIndex should be checked.
I think, a simple regex replace would be better and more conform to the RFC2397:
java.util.Base64.getDecoder().decode(b64DataString.replaceFirst("data:.+,", ""))
The RFC states that the data: and the , are the required prefixes for a data url, therefore it is wise to match for them.
I use ImageIO to save Base64 image string to a file:
public static String decodeBase64AndSaveImage(String data) throws IOException, BadRequestException {
try {
if (data == null) {
return null;
}
String base64Image = data.split(",")[1];
byte[] imageBytes = DatatypeConverter.parseBase64Binary(base64Image);
BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageBytes));
String imageId = generateRandomKey(15);
ImageIO.write(img, "png", getImageFile(imageId));
return imageId;
} catch (IllegalArgumentException e) {
throw new BadRequestException("Bad image data");
}
}
I pass the following string to this method:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAADklEQVQIW2NgQAXGZHAAGioAza6+Hk0AAAAASUVORK5CYII=
In the following test I check that the if the saved content to the file is the same as what was passed to the method:
byte[] base64ImageData = Base64.encodeBase64(FileUtils.readFileToByteArray(imageFile));
Assert.assertEquals("wrong image data stored", DUMMY_IMAGE
.split(",")[1], new String(base64ImageData,
StandardCharsets.UTF_8));
But it returns a different string:
iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAADklEQVR42mNgQAXGZHAAGioAzTktUZoAAAAASUVORK5CYII=
Why does this happen ?
Note 1
It doesn't compare data:image/png;base64, so it's not the reason that it fails.
You are base64 decoding the string, using ImageIO to create a BufferedImage, converting it back to a PNG, and re-base64 encoding this result.
byte[] imageBytes = DatatypeConverter.parseBase64Binary(base64Image);
BufferedImage img = ImageIO.read(new
ByteArrayInputStream(imageBytes));
String imageId = generateRandomKey(15);
// re-encode
ImageIO.write(img, "png", getImageFile(imageId));
This all works fine. But the image encoder is encoding the image in a slightly different way to the original. They are both though valid PNG files and both valid base64 strings.
I decoded both strings and found they produced valid PNG files which look identical, but were encoded in different ways.
how to convert gif to base64?
here's what i try so far
public static String convertImageToBase64(String urlString, String type ){
String imageString = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
URL url = new URL(urlString);
BufferedImage img = ImageIO.read( url );
ImageIO.write(img, type, bos);
byte[] imageBytes = bos.toByteArray();
BASE64Encoder encoder = new BASE64Encoder();
imageString = encoder.encode(imageBytes);
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
return imageString;
}
code above is working, but it lost the animation
Most likely the class BufferedImage does not support images with animation. So the code opens and parses the image only to the first frame.
Instead try directly getting the bytes with URL.openStream and then just convert the downloaded bytes to base64.
Notice that this way you can't be sure that the downloaded file is actually an image since you are not opening it at all. This may or may not be needed.
You have to use
public String encodeToString(byte[] src)
of class BASE64.Encoder (from java 8)
I'm assuming what you want is a Base64 representation of the GIF file itself, not the ImageIO representation. If you have an older version of Java without built-in Base64 support, Apache Commons Codec will do the job. Read the file into a byte array using URL.openStream(), not with ImageIO, then call Base64.encodeBase64String. If you want the result URL encoded, call Base64.encodeBase64URLSafe instead.
If you actually want the ImageIO representation, then you're stuck with losing the animation.
I am trying to convert byte[] array to buffered image so than i can resize the image..but problem is conversion always turned into null.here is my code..
ByteArrayInputStream bais = new ByteArrayInputStream(user.getUser_image());
//Here user.getUser_image() returns byte[] returned from server..
try {
BufferedImage image = ImageIO.read(bais);
System.out.println("============><================"+image);//Here it prints null
BufferedImage scaledImage = Scalr.resize(image,48);
}
.....and so on
It means that the ImageIO class is not able to select an appropriate ImageReader. The purpose of this could be corrupted byte array or unsupported image type. Try to debug it.
I use following code for get bitmap from string but i get null bitmap. So please guide me.
byte[] Image_getByte = Base64.decode(img);
ByteArrayInputStream bytes = new ByteArrayInputStream(Image_getByte);
BitmapDrawable bmd = new BitmapDrawable(bytes);
Bitmap bitmap=bmd.getBitmap();
Log.v("log","Home bitmap "+bitmap);
i.setImageBitmap(bitmap);
use BitmapFactory.decodeByteArray(Image_getByte)
here you don't need any String, after getting the byte array, just pass it in the mentioned method which returns Bitmap
The javadoc for getBitmap() says:
"Returns the bitmap used by this drawable to render. May be null."
If img is base 64 String use the following source to get the bitmap from base 64 string.
byte[] source=img.getBytes();
byte[] Image_getByte = Base64.decode(source);
Bitmap bitmap = BitmapFactory.decodeByteArray(Image_getByte, 0,Image_getByte.length);
imageView.setImageBitmap(bitmap);
This may help you
Please consider 'ImageContents' as String which contains image data.
byte[] imageAsBytes = Base64.decode(ImageContents.getBytes());
ImageView image = (ImageView)this.findViewById(R.id.ImageView);
image.setImageBitmap(
BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
);
ImageView :In Android, you can use “android.widget.ImageView” class to
display an image file
BitmapFactory:Creates Bitmap objects from various sources, including
files, streams, and byte-arrays.
For more information about BitmapFactory see here