I've got a problem. I need to save a java BufferedImage object in an String. Convert this String on the Android application into Bitmap. How can I achieve this? Or maybe you can recommend me the other way to transfer image information in the String format.
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();
imageString = Base64.getEncoder().encodeToString(imageBytes);
bos.close();
} catch (IOException e) {
log.error("Can't encode to String");
}
return imageString;
}
Base64 encoding and decoding of images using Java 8:
public static String imgToBase64String(final RenderedImage img, final String formatName) {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ImageIO.write(img, formatName, Base64.getEncoder().wrap(os));
return os.toString(StandardCharsets.ISO_8859_1.name());
} catch (final IOException ioe) {
throw new UncheckedIOException(ioe);
}
}
public static BufferedImage base64StringToImg(final String base64String) {
try {
return ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(base64String)));
} catch (final IOException ioe) {
throw new UncheckedIOException(ioe);
}
}
hope so will work,
enjoy your code:)
Related
Firstly, I have to convert the image into Base64 and then calculate the DPI of an image by converting base64 to buffered Image.
Here is some code that I tried and that works well for image.PNG(.png) format but return -1(wrong output) in other formats like(.jpg)...!
But I need this to also work for other formats too.
private static float base64toBuffer(String inputbuffer) throws IOException, ImageReadException{
byte[] Rimage=decodeToImage(inputbuffer);
final org.apache.sanselan.ImageInfo imageInfo = Sanselan.getImageInfo(Rimage);
final int physicalWidthDpi = imageInfo.getPhysicalWidthDpi();
final int physicalHeightDpi = imageInfo.getPhysicalHeightDpi();
return physicalWidthDpi;
}
private static byte[] buffertoByte(String imageString) {
byte[] imageByte;
try {
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(imageString);
return imageByte;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
I want to serialize a RenderImage as a text string so that I can java a Jason-like file with some fields (Name, Date, Photo).
I would like to use
String s = String.format("%s:%s,%s:%s,%:%s",
"name", my_name,
"date", date,
"photo", someFunctionToGenerateAStringForTheImage(RenderedImage));
And save s to a file.
Currently, I am using this:
public static byte[] imageToByteArray(RenderedImage img) {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
ImageIO.write(img, "png", out);
out.flush();
return out.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
And I call it as such:
String imageAsString =new String(Util.imageToByteArray(post.getImage()));
I deserialize the strings using the following function:
public static RenderedImage byteArrayToImage(byte[] bytes) {
try (ByteArrayInputStream in = new ByteArrayInputStream(bytes)) {
return ImageIO.read(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Thus I call it as such byteArrayToImage(imageAsString.getBytes());
Unfortunately, this approach is not working, the objects produced aren't the same... I would like to it using a String.format because my code is much more complex and full of recursive calls, so I want the simplest way of achieving this.
What can you recommend me?
You can try using Data URL:
public static String imageToDataUrl(RenderedImage img) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try {
ImageIO.write(img, "png", bytes);
} catch (IOException e) {
throw new RuntimeException(e);
}
String data = DatatypeConverter.printBase64Binary(bytes.toByteArray()),
//proper data url format
dataUrl = "data:image/png;base64," + data;
return dataUrl;
}
And to deserialise:
public static RenderedImage dataUrlToImage(String dataUrl) {
String data = dataUrl.substring(dataUrl.indexOf(',')+1);
byte[] bytes = DatatypeConverter.parseBase64Binary(data);
try (ByteArrayInputStream in = new ByteArrayInputStream(bytes)) {
return ImageIO.read(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Create class
class MyImage {
String name;
Date date;
String photo;
}
and use any json lib, for example GSON:
String s = new GSON.toJson(myImage).replace('{'}.replace{'}');
MyImage myImage = new GSON.fromJson("{"+s+"}", MyImage.class);
Update:
if you have problem with serialization image try to use:
String s = new String(utf8Bytes, "UTF8");
byte[] utf8Bytes = original.getBytes("UTF8");
instead of
String s = new String(utf8Bytes);
byte[] defaultBytes = original.getBytes();
I'm using apache-commons-sanselan.jar API to remove EXIF content from only JPEG file.
How to remove this content from other file extensions?
BufferedImage image = ImageIO.read(new File("image.jpg"));
ImageIO.write(image, "jpg", new File("image.jpg"));
Metadata isn't read when you read an image. Just write it back. Replace jpg with the extension you want.
Sources:
How to remove Exif,IPTC,XMP data of a png image in Java
How can I remove metadata from a JPEG image in Java?
In addition to #little-child answer
code:
public static void removeExifTag(final String sourceImageFile, final File destinationImageFile) throws IOException, ImageReadException, ImageWriteException {
try (
OutputStream os = new FileOutputStream(destinationImageFile);
BufferedOutputStream bos = new BufferedOutputStream(os);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
){
BufferedImage originalImage = ImageIO.read(new File(sourceImageFile));
originalImage.flush();
ImageIO.write( originalImage,"jpg", baos );
byte[] imageInByte = baos.toByteArray();
new ExifRewriter().removeExifMetadata(imageInByte, bos);
baos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ImageReadException e) {
e.printStackTrace();
} catch (ImageWriteException e) {
e.printStackTrace();
}
}
I'm trying to load a gif from a url to be displayed in an Imageview, store it in the internal storage and then later read it again. But it refuses to either store the image or reading it, not sure which one because I get no exceptions. Loading the image to the imageview works. The first method below (loadImage())
public Bitmap loadImage(String url){
Bitmap bm = null;
URL request;
try {
if(url!=null){
request = new URL(url);
InputStream is = request.openStream();
bm = BitmapFactory.decodeStream(is);
is.close();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bm;
}
public String writeGifToInternalStorage (Bitmap outputImage) {
try {
String fileName = String.valueOf(Calendar.getInstance().getTimeInMillis());
ByteBuffer byteBuffer = ByteBuffer.allocate(outputImage.getByteCount());
outputImage.copyPixelsToBuffer(byteBuffer);
byteBuffer.flip();
byte[] data = new byte[byteBuffer.limit()];
byteBuffer.get(data);
FileOutputStream fos = ctx.openFileOutput(fileName, Context.MODE_PRIVATE);
fos.write(data);
fos.close();
return fileName;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public Bitmap readFileFromInternalStorage(String filename) {
if (filename == null) return null;
FileInputStream fis;
try {
fis = ctx.openFileInput(filename);
return BitmapFactory.decodeStream(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
Any ideas of whats wrong?
Your method readFileFromInternalStorage read an encoded image from the file system. This image file should be what you receive from the server.
For that, you need to save the image when you receive it from the server, for example like so:
InputStream is = new BufferedInputStream(request.openStream());
String fileName = String.valueOf(Calendar.getInstance().getTimeInMillis());
FileOutputStream fos = ctx.openFileOutput(fileName, Context.MODE_PRIVATE);
byte[] buffer = new byte[1024];
int red = 0;
while ((red = is.read(buffer)) != -1) {
fos.write(buffer,0, red);
}
fos.close();
is.close();
Then, your image is saved to the disk, and you can open it using your readFileFromInternalStorage method.
Also, if you use HttpClient instead of URL, I wrote a one-liner for downloading a file: Android download binary file problems
I'm trying to grab (with the method below) an image from the internet and do some canvas work with. but sometimes i'm having outOfMemory exception. So i'm wondering if is there a way to load the inputStream directly in the memory card instead of the internal memory.
private Bitmap LoadImageFromWebOperations(String url)
{
try {
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
bitmap = ((BitmapDrawable)d).getBitmap().copy(Config.ARGB_8888, true);
return bitmap;
}catch (Exception e) {
System.out.println("Exc="+e);
return null;
}
}
the logcat says that the exception is due to that line :
Drawable d = Drawable.createFromStream(is, "src name");
Thx in advance!
I took this code from Fedor Vlasov's lazylist demo:
Lazy load of images in ListView.
First you need to create a function to copy your input stream to file output stream:
public static void CopyStream(InputStream is, OutputStream os)
{
final int buffer_size=1024;
try
{
byte[] bytes=new byte[buffer_size];
for(;;)
{
int count=is.read(bytes, 0, buffer_size);
if(count==-1)
break;
os.write(bytes, 0, count);
}
}
catch(Exception ex){}
}
Then get a cache folder:
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"MyCacheDir");
else
cacheDir=context.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
Then load your bitmap:
private Drawable getBitmap(String url)
{
String filename=URLEncoder.encode(url);
File f= new File(cacheDir, filename);
try {
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
InputStream is = conn.getInputStream();
OutputStream os = new FileOutputStream(f);
CopyStream(is, os);
os.close();
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(f));
return new BitmapDrawable(bitmap);
} catch (Exception ex){
ex.printStackTrace();
return null;
}
}