I have a string, which i am converting it into bytes[] and then i code it to bring back to image but the problem is that it is not creating it back to the image
BufferedReader reader2 = new BufferedReader(new FileReader("e:\\imageinString.txt"));
String buffer, lined = "";
while ((buffer = reader2.readLine()) != null) {
lined = lined + buffer;
}
byte[] byteArray = lined.getBytes("UTF-16");
InputStream in = new ByteArrayInputStream(byteArray);
BufferedImage bImageFromConvert = ImageIO.read(in);
ImageIO.write(bImageFromConvert, "bmp", new File("e:\\ppp.bmp"));
reader2.close();
I am getting this error but I am getting this on console
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 imagereading.Imagereading.main(Imagereading.java:47)
This will help you.
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g2 = image.createGraphics();
g2.drawString(s, x, y);
...
g2.dispose();
ImageIO.write(image, "jpg", file);
Or if you prefer to export to png then you can have an image that supports transparency.
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Related
I have a function generateImageOutput below to write BufferedImage to jpeg file.
public boolean generateImageOutput(BufferedImage image, String filename){
//The image is written to the file by the writer
File file = new File( projectFolder+"/data/"+filename+".jpg");
//Iterator containing all ImageWriter (JPEG)
Iterator encoder = ImageIO.getImageWritersByFormatName("JPEG");
ImageWriter writer = (ImageWriter) encoder.next();
//Compression parameter (best quality)
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(1.0f);
//Try to write the image
try{
ImageOutputStream outputStream = ImageIO.createImageOutputStream(file);
writer.setOutput(outputStream);
writer.write(null, new IIOImage(image, null, null), param);
outputStream.flush();
writer.dispose();
outputStream.close();
}catch(IOException e){
e.printStackTrace();
System.out.println(e.toString());
return false;
}
return true;
}
It works for some, but it fails for a BufferedImage converted from base64 string:
String encodedString = JSON.parseObject(string).getString("image");
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
ByteArrayInputStream bis = new ByteArrayInputStream(decodedBytes);
buffered_image = ImageIO.read(bis);
When writing the above buffered_image to jpeg using generateImageOutput, it raises exception :
javax.imageio.IIOException: Bogus input colorspace
at java.desktop/com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeImage(Native Method)
at java.desktop/com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeOnThread(JPEGImageWriter.java:1007)
at java.desktop/com.sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:371)
The string encodedString has no issue, I have sucessfully converted it to an image online.
How can I resolve the exception ?
According to #J.doe Alpha channel must be remove. I have a code that removes the Alpha channel. The code below was to determine whether or not the image has alpha channel. If the image has alpha channel it will create an image without alpha channel.
private static BufferedImage removeAlphaChannel(BufferedImage img) {
if (!img.getColorModel().hasAlpha()) {
return img;
}
BufferedImage target = createImage(img.getWidth(), img.getHeight(), false);
Graphics2D g = target.createGraphics();
// g.setColor(new Color(color, false));
g.fillRect(0, 0, img.getWidth(), img.getHeight());
g.drawImage(img, 0, 0, null);
g.dispose();
return target;
}
private static BufferedImage createImage(int width, int height, boolean hasAlpha) {
return new BufferedImage(width, height, hasAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
}
Finally I find that the reason is the image has an ALPHA channel.
Looks like JPEG doesn't handle the alpha channel correctly in this context. For me saving the image as PNG did the trick.
How can I save BufferedImage with TYPE_INT_ARGB to jpg?
Program generates me that image:
And it's OK, but when I save it in that way:
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(byteStream);
try {
ImageIO.write(buffImg, "jpg", bos);
// argb
byteStream.flush();
byte[] newImage = byteStream.toByteArray();
OutputStream out = new BufferedOutputStream(new FileOutputStream("D:\\test.jpg"));
out.write(newImage);
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The result is:
Understand that this is due to the alpha layer, but don't know how to fix it. Png format does not suit me, need jpg.
OK!
I've solved it.
Everything was pretty easy. Don't know is it a good decision and how fast it is. I have not found any other.
So.. everything we need is define new BufferedImage.
BufferedImage buffImg = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = buffImg.createGraphics();
// ... other code we need
BufferedImage img= new BufferedImage(buffImg.getWidth(), buffImg.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.drawImage(buffImg, 0, 0, null);
g2d.dispose();
If there any ideas to improve this method, please, your welcome.
Images having 4 color channels should not be written to a jpeg file. We can convert between ARGB and RGB images without duplicating pixel values. This comes in handy for large images. An example:
int a = 10_000;
BufferedImage im = new BufferedImage(a, a, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = im.createGraphics();
g.setColor(Color.RED);
g.fillRect(a/10, a/10, a/5, a*8/10);
g.setColor(Color.GREEN);
g.fillRect(a*4/10, a/10, a/5, a*8/10);
g.setColor(Color.BLUE);
g.fillRect(a*7/10, a/10, a/5, a*8/10);
//preserve transparency in a png file
ImageIO.write(im, "png", new File("d:/rgba.png"));
//pitfall: in a jpeg file 4 channels will be interpreted as CMYK... this is no good
ImageIO.write(im, "jpg", new File("d:/nonsense.jpg"));
//we need a 3-channel BufferedImage to write an RGB-colored jpeg file
//we can make up a new image referencing part of the existing raster
WritableRaster ras = im.getRaster().createWritableChild(0, 0, a, a, 0, 0, new int[] {0, 1, 2}); //0=r, 1=g, 2=b, 3=alpha
ColorModel cm = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB).getColorModel(); //we need a proper ColorModel
BufferedImage imRGB = new BufferedImage(cm, ras, cm.isAlphaPremultiplied(), null);
//this image we can encode to jpeg format
ImageIO.write(imRGB, "jpg", new File("d:/rgb1.jpg"));
I want to send ImageIcon to database using jdbc.
I need to File object to do that.
How to convert ImageIcon to File wihout saving it into disk?
File fBlob = new File(imageIcon.getImage());
FileInputStream is = new FileInputStream ( fBlob );
preparedStatement.setBinaryStream (3, is, (int) fBlob.length() );
May be you could try to get a byte array from the imageIcon and then write it to the database. Something like this :
BufferedImage bi = getBufferedImage(imageIcon.getImage());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, formatType, baos);
byte[] byteArray= baos.toByteArray();
preparedStatement.setBytes(1, byteArray);
EDIT :
Use this method to convert the Image to a BufferedImage :
public static BufferedImage getBufferedImage(Image img)
{
if (img instanceof BufferedImage)
{
return (BufferedImage) img;
}
BufferedImage bimage = new BufferedImage(img.getWidth(null),
img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
// Return the buffered image
return bimage;
}
I'm trying to export example GRAL Pie plot to jpg using:
private byte[] getJpg() throws IOException {
BufferedImage bImage = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bImage.createGraphics();
DrawingContext drawingContext = new DrawingContext(g2d, DrawingContext.Quality.QUALITY,
DrawingContext.Target.BITMAP);
PiePlot plot = getPlot();
plot.draw(drawingContext);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bImage, "jpg", baos);
baos.flush();
byte[] bytes = baos.toByteArray();
baos.close();
return bytes;
}
But it renders as black rectangle with some legend information (legend is ok). Who knows the right way to render JPG from GRAL plot?
Shurely, I found a built'in solution, DrawableWriter. Now the export looks like this:
private byte[] getJpg() throws IOException {
BufferedImage bImage = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D) bImage.getGraphics();
DrawingContext context = new DrawingContext(g2d);
PiePlot plot = getPlot();
plot.draw(context);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DrawableWriter wr = DrawableWriterFactory.getInstance().get("image/jpeg");
wr.write(plot, baos, 800, 600);
baos.flush();
byte[] bytes = baos.toByteArray();
baos.close();
return bytes;
}
Thanks to developers! Everything is done already.
I'm using iText to create a PDF417 bar code like so:
private InputStream getBarcode() throws Exception {
BarcodePDF417 barcode = new BarcodePDF417();
barcode.setText("Sample bar code text");
Image image = barcode.getImage();
image.scalePercent(50, 50 * barcode.getYHeight());
return new ByteArrayInputStream(image.getRawData());
}
I need to convert the CCITT format returned by barcode.getImage() to either JPG, GIF, or PNG so I can include it in a document I'm creating in JasperReports.
How about something like this?
BarcodePDF417 barcode = new BarcodePDF417();
barcode.setText("Bla bla");
java.awt.Image img = barcode.createAwtImage(Color.BLACK, Color.WHITE);
BufferedImage outImage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
outImage.getGraphics().drawImage(img, 0, 0, null);
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
ImageIO.write(outImage, "png", bytesOut);
bytesOut.flush();
byte[] pngImageData = bytesOut.toByteArray();
FileOutputStream fos = new FileOutputStream("C://barcode.png");
fos.write( pngImageData);
fos.flush();
fos.close();
The solution I came up with:
private Image getBarcode() throws Exception {
BarcodePDF417 barcode = new BarcodePDF417();
barcode.setText("Sample bar code text");
barcode.setAspectRatio(.25f);
return barcode.createAwtImage(Color.BLACK, Color.WHITE);
}
JasperReports supports the java.awt.Image type for images used in a report.