Create image file from raw string data - java

for example, i have String like this:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHQAAAB0CAYAAABUmhYnAAAEd0lEQVR4Xu2c0ZLjIAwEk///6GzVvZlspWtWksNRnVcwiGmNwHaS5+v1ej38HKPAU6DHsPy3EIGexVOgh/EUqEBPU+Cw9biHCvQwBQ5bjg4V6GEKHLYcHSrQwxQ4bDk6VKCHKXDYcnSoQA9T4LDllB36fD5vlWR9fUvz0+ve9fp0/O7FU7w0n0CXhBSoDiXTRO06FBKKBLLkLvlGgkTp+UvndPzu/ul46Xq7x2/fQ8kR0wtOBaL+1J6uZ+3fPb5Aw0PRtxOWEkigAr3mCJUMuk9cM45uG3ZvJwel8dN4byW8+r1cgWYPVgRaLIlpwqWCT1cgHbr8skOgYUqkgtHwVYfQKZTiTW8rdCgQFWjtt2Pjty3TGdztOB0aHlosuVcHpglJ+h3nUFow7bE6dDOHCjRN2fBty917qEAF+jEHaI+bTlhK0Nsf/aUBpXtYdXy6noDS9dTePf74oYgWRO3dC6b57k6o7vUJFAh3Cz6dMAIV6FWB9FCQlry1f/ejQXLgt9eX6tXu0DSAtL9APysm0OYHI2mCUgVKxxOoQNOcubc/7XnF5yj3LuYPs5Ud+oc5Ry8R6GEpK1CBjlaMuwcvl1xyBC2I8im9T0xva6pPbtL1V+MjPQW6KEQJRAlAggs0vK2oCibQ4g9+LbnXb96THlQBvl5y0yclqYNQAKgAVGIJQHWPpfjf4uv+bUsagECvClCCkL46VIdecyQtKZRhlKGW3OG3LekeQ0DSBOk+1VLCdbdTAqfzlUuuQFPJe/fM9kORQAV6UYBKJslF11NJS0s8xZO2U3zpeO0lNw2g2+HV8dLbKJov1aMKWKDFfyITKKRsegqmjE7H06FpTRHoRwUoQUnu9pJLh4z0EFMdjwRI46ESWwVC8VK7QMN/TRHookDqCB1Knry261AdmmXMdG86xabzd49H83fP1+5QWkB3e7sg4eu06nra46++4K4uqHp9uyACrSKpXS/Q5kMRnUJruN6vnr7Po/VMn9KrepX3UBKgGmD1UVw6P61HoKmi0F+HfhZIhy766NDhU2F66CEgzQXjQRUjjb8aX7tDaYFpwKkgAi0SSAUXaO0Pjkk/HUoKFQ9p0wm/hjcONC2B6W3B24KKv1ZLx0vzgfQoFsyHQJe3LQINHUEZrUNre6wO1aHLw+AvO5QOHdReLbE0/vSeedyhKBWUDh00XpoAAg2/EkIAqD0FlPYXqEDp3Pix/b8/FKUOIMem7fR6j8Yr0fvlYoEWK4JAw0dplOE6dLnrqH5JrCp4NcMFejPQ6h7RnTAUT/eTKkpYiidtH99D04C6bwvS+QX65W8sUMkVaKgAlcRwuLfuNL5Ah/fQKkC6Pi2JKXB6NEjxUTslKF1P7e17KE1YbRfoZwUFuuijQ4v/l5s6VocOOzQFYv9ZBcoldzY8R08VEGiq2Ob9Bbo5oDQ8gaaKbd5foJsDSsMTaKrY5v0FujmgNDyBpopt3l+gmwNKwxNoqtjm/QW6OaA0PIGmim3eX6CbA0rDE2iq2Ob9Bbo5oDS8H8eCMw7yCzx+AAAAAElFTkSuQmCC
i want to convert it back to an image file. here's what i've tried:
public void dumpFromRawData(String rawData, String wheretoPut) throws Exception{
byte[] imageByte = rawData.getBytes();
BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(imageByte));
File file = new File(wheretoPut);
ImageIO.write(bufferedImage, "png", file);
}
where rawData is the example string above, and wheretoPut is the new image directory.. for example D:\\image.png
but when i run it, it gives me this:
Exception in thread "main" java.lang.IllegalArgumentException: image == null!
at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925)
at javax.imageio.ImageIO.getWriter(ImageIO.java:1592)
at javax.imageio.ImageIO.write(ImageIO.java:1520)
how could i resolve this? or is this not the correct way to convert it back to image?

The data of your image seems to be base64 encoded so you can not just convert this string into a byte array.
So you should use something like:
byte[] imageByte = Base64.decode(rawData, Base64.DEFAULT);

i finally found the solution. Thans #Chris623 for enlightening me :D
first, i need to separate the 'header' of the string file.. the data:image/png;base64, string, and then decode it to byte[]
String separator = ",";
String encoded = rawData.split(separator)[1];
byte[] decodedByte = Base64.getDecoder().decode(encoded.getBytes(StandardCharsets.UTF_8));
and then the rest of process is still the same.. the full method looks like this:
public void dumpFromRawData(String rawData, String wheretoPut, String fileName) throws Exception{
String separator = ",";
if(rawData.contains(separator)) {
// use this when the decoded string contains "," separator, like data:image/png;base64,
String encoded = rawData.split(separator)[1];
byte[] decodedByte = Base64.getDecoder().decode(encoded.getBytes(StandardCharsets.UTF_8));
// you can use this
// Path destinationFile = Paths.get(wheretoPut, fileName);
// Files.write(destinationFile, decodedByte);
// or this
BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(decodedByte));
File file = new File(wheretoPut+fileName);
ImageIO.write(bufferedImage, "png", file);
System.out.println("File has been Written as " + wheretoPut + fileName);
} else {
System.out.println("i haven't think about it yet.");
}
}

Related

Convert String which is URL of image to byte array

I have an image content coming from Spring RestTemplate get result:
String url = "https://is2-ssl.mzstatic.com/image/" +
"thumb/Purple114/v4/15/a1/68/15a1681f-dec4-b01f-4362" +
"-e9ff1ece9c09/AppIcon-1x_U007emarketing-0-10-0-0-85" +
"-220-0.png/60x60bb.png";
String imageAsString = restTemplate.getForObject(url, String.class);
I know this is not a right way to fetch image by RestTemplate. But I should keep it for my old code.
How can I convert this value to right image byte array format?
imageAsString.getBytes() -> this is not the same with restTemplate.getForObject(url, byte[].class);
If you have an image URL, you can first read it into a BufferedImage and then write it to a FileOutputStream as follows:
public static void main(String[] args) throws IOException {
URL url = new URL("https://is2-ssl.mzstatic.com/image/" +
"thumb/Purple114/v4/15/a1/68/15a1681f-dec4-b01f-4362" +
"-e9ff1ece9c09/AppIcon-1x_U007emarketing-0-10-0-0-85" +
"-220-0.png/60x60bb.png");
BufferedImage bufferedImage = ImageIO.read(url);
ImageIO.write(bufferedImage, "png",
new FileOutputStream("resources/bufferedImage.png"));
}
Here is the image: bufferedImage.png

How could I convert png binary data into bmp binary data in JAVA?

I got my binary data from database which is in PNG format. Now, I need to change the format to BMP and then convert it to a string by Base64.
My logic is PNG binary-->BMP binary-->BMP base64 String.
My Code is as below. The input "data" is the PNG binary, imageFormat="BMP".
public static String imageToBase64 (byte[] data, String imageFormat) throws IOException{
BufferedImage imag=ImageIO.read(new ByteArrayInputStream(data));
ByteArrayOutputStream baos=new ByteArrayOutputStream(1000);
ImageIO.write(imag, imageFormat, baos);
String base64String=Base64.encodeBytes(baos.toByteArray());
return base64String;
}
However, the result always return empty. Can anyone help me to solve this problem?
Thanks
You need to use the Java API to write to a new BMP file. Based on your code this is how it does what you asked.
public static String imageToBase64(byte[] data, String imageFormat) throws IOException {
BufferedImage imag = ImageIO.read(new ByteArrayInputStream(data));
BufferedImage bmpImg = new BufferedImage(imag.getWidth(), imag.getHeight(), BufferedImage.TYPE_INT_RGB);
bmpImg.createGraphics().drawImage(imag, 0, 0, Color.WHITE, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bmpImg, imageFormat, baos);
String base64String = Base64.getEncoder().encodeToString(baos.toByteArray());
return base64String;
}
Please note I used "bmp" (lowercase) instead of "BMP". Not sure if this matters. Enjoy.

FileNotFoundException when reading a BufferedImage

I'm trying to crop an image received from a form upload. Before I crop it I save it, then I retrieve it again as a BufferedImage (because I don't know how to turn a part into a buffered Image). I then crop this image, but when I try to save it again I get a java.io.FileNotFoundException (access denied)
The first image gets saved correctly, I get the exception when I try to pull it back.
Is it possible to turn my part into a buffered image and then save it? Instead of doing double work. or else is there some fix to my below code.
String savePath = "path";
File fileSaveDir = new File(savePath);
if (!fileSaveDir.exists()) {
fileSaveDir.mkdir();
}
for (Part part : request.getParts()) {
//functionality to ormit non images
String fileName = extractFileName(part);
part.write(savePath + "/" + fileName);
String imagePath = savePath + "/" + fileName;
BufferedImage img = null;
try {
img = ImageIO.read(new File(imagePath));
img = img.getSubimage(0, 0, 55, 55);
ImageIO.write(img, "jpg", fileSaveDir);
} catch (IOException e) {
System.out.println(e);
}
}
ImageIO.write((RenderedImage im, String formatName, File output));
Parameters:
im a RenderedImage to be written.
formatName a String containg the informal name of the format.
output a File to be written to.
As per documentation output file parameter is the file object where it would be image written where you have passed the parent directory file object.

Error while converting image to byte[] in Java using WritableRaster and DataBufferByte.

I am trying to convert image to byte[] using code
public static byte[] extractBytes(String ImageName) throws IOException {
// open image
File imgPath = new File(ImageName);
BufferedImage bufferedImage = ImageIO.read(imgPath);
// get DataBufferBytes from Raster
WritableRaster raster = bufferedImage.getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
return (data.getData());
}
When I am testing it using code
public static void main(String[] args) throws IOException {
String filepath = "image_old.jpg";
byte[] data = extractBytes(filepath);
System.out.println(data.length);
BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
File outputfile = new File("image_new.jpg");
ImageIO.write(img, "jpeg", outputfile);
}
I am getting data.length = 4665600 and getting error
Exception in thread "main" java.lang.IllegalArgumentException: image == null!
at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925)
at javax.imageio.ImageIO.getWriter(ImageIO.java:1591)
at javax.imageio.ImageIO.write(ImageIO.java:1520)
at com.medianet.hello.HbaseUtil.main(HbaseUtil.java:138)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
But when I am changing my extractBytes code to
public static byte[] extractBytes (String ImageName) throws IOException {
ByteArrayOutputStream baos=new ByteArrayOutputStream();
BufferedImage img=ImageIO.read(new File(ImageName));
ImageIO.write(img, "jpg", baos);
baos.flush();
return baos.toByteArray();
}
I am getting data.length = 120905 and getting success(image.jpg getting created in the desired location)
The thing is, the first version of extractBytes reads an image, and just returns the image's pixels as an array of bytes (assuming it uses DataBufferByte). These bytes are not in a file format, and are useless without extra information, such as width, height, color space etc. ImageIO can't read these bytes back, and because of this, null is returned (and assigned to img, later causing an IllegalArgumentException from ImageIO.write(...)).
The second version decodes the image, then encodes it again in JPEG format. This is a format ImageIO will be able to read, and you get an image (assigned to img) as you expect.
However, you code seems like just a very, very CPU-expensive way of copying images (you decode an image, then encode, then decode again, before finally encoding)... For JPEG files this decode/encode cycle will also degrade the image quality. Unless you are planning to use the image data for anything, and just want to copy an image from one place to another, don't use ImageIO and BufferedImages. These types are intended for image manipulation.
Here's a modified version of your main method:
public static void main(String[] args) throws IOException {
byte[] buffer = new byte[1024];
File inFile = new File("image_old.jpg");
File outFile = new File("image_new.jpg");
InputStream in = new FileInputStream(inFile);
try {
OutputStream out = new FileOutputStream(outFile);
try {
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
}
finally {
out.close();
}
}
finally {
in.close();
}
}
(It's possible to write this better/more elegant using try-with-resources in Java 7, or NIO2 Files.copy in Java 8, but I leave that to you. :-) )

In Java is it possible to convert a BufferedImage to an IMG Data URI?

I have created a graphical image with the following sample code.
BufferedImage bi = new BufferedImage(50,50,BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g2d = bi.createGraphics();
// Draw graphics.
g2d.dispose();
// BufferedImage now has my image I want.
At this point I have BufferedImage which I want to convert into an IMG Data URI. Is this possible? For example..
<IMG SRC="data:image/png;base64,[BufferedImage data here]"/>
Not tested, but something like this ought to do it:
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(bi, "PNG", out);
byte[] bytes = out.toByteArray();
String base64bytes = Base64.encode(bytes);
String src = "data:image/png;base64," + base64bytes;
There are lots of different base64 codec implementations for Java. I've had good results with MigBase64.
You could use this solution which doesn't use any external libraries. Short and clean! It uses a Java 6 library (DatatypeConverter). Worked for me!
ByteArrayOutputStream output = new ByteArrayOutputStream();
ImageIO.write(image, "png", output);
DatatypeConverter.printBase64Binary(output.toByteArray());
I use Webdriver, get captcha, like this below:
// formatName -> png
// pathname -> C:/Users/n/Desktop/tmp/test.png
public static String getScreenshot(WebDriver driver, String formatName, String pathname) {
try {
WebElement element = driver.findElement(By.xpath("//*[#id=\"imageCodeDisplayId\"]"));
File screenshot = element.getScreenshotAs(OutputType.FILE);
// base64 data
String base64Str = ImageUtil.getScreenshot(screenshot.toString());
return base64Str;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String getScreenshot(String imgFile) {
InputStream in;
byte[] data = null;
try {
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
String base64Str = new String(Base64.getEncoder().encode(data));
if (StringUtils.isAnyBlank(base64Str)) {
return null;
}
if (!base64Str.startsWith("data:image/")) {
base64Str = "data:image/jpeg;base64," + base64Str;
}
return base64Str;
}

Categories