I'm doing cropping and saving inputstream on database. For jpg it's working fine. But when I'm trying to upload png file it's showing like this:
Here is the code:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedImage img = org.getSubimage(x1, y1, w, h);
ImageIO.write(img, "jpg", baos);
is = new ByteArrayInputStream(baos.toByteArray());
Related
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 have some issues that I am having a hard time solving.
I made a short code snippet :
BufferedImage image = ImageIO.read(new ByteArrayInputStream(payload));
BufferedImage thumbImg = Scalr.resize(image, Method.QUALITY,
Mode.AUTOMATIC, WIDTH, HEIGHT, Scalr.OP_ANTIALIAS);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Base64OutputStream b64s = new Base64OutputStream(baos);
ImageIO.write(thumbImg, DATA_TYPE, b64s);
return baos.toByteArray();
The returned thumbnail/byte is trimmed down. It deletes the bottom part and shows just a transparent area.
What I want is to have a scaled down image without removing some parts of it.
The purpose for this is to return a base64 to my html project.
Yea.. I just changed my logic for creating a base64 output.
Instead of having it write in Base64OutputStream of Apache Commons Framework.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Base64OutputStream b64s = new Base64OutputStream(baos);
ImageIO.write(thumbImg, DATA_TYPE, b64s);
return new ThumbnailPayload(baos.toByteArray()));
I did this instead
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(thumbImg, DATA_TYPE, baos);
return new ThumbnailPayload(Base64.encodeBase64(baos.toByteArray()));
Currently it is working. But if you guys can suggest another way with an explanation before the day ends, that would be awesome and helpful.
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 am reading a image file in a servlet from an http request. I want to crop it as a square and write it to file. I can achieve that with the following code but i am using a temporary file to write the original image first. How can I do that without using a temp file
File tempFile = new File(saveFileFrameTemp);
fileOut = new FileOutputStream(tempFile);
fileOut.write(dataBytes, startPos, (endPos - startPos));
fileOut.flush();
fileOut.close();
BufferedImage fullFrame = ImageIO.read(tempFile);
int height = fullFrame.getHeight();
int width = fullFrame.getWidth();
if (height > width)
ImageIO.write( fullFrame.getSubimage(0, (height-width)/2, width, width), "jpg", new File(saveFileFrame));
else
ImageIO.write( fullFrame.getSubimage((width-height)/2, 0, height, height), "jpg", new File(saveFileFrame));
tempFile.delete();
You cannot crop a BufferedImage without creating a new BufferedImage as a side effect
I solved it using ByteArray.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(dataBytes, startPos, (endPos - startPos));
BufferedImage fullFrame = ImageIO.read(new ByteArrayInputStream(baos.toByteArray()));
And I used this link in the process http://www.mkyong.com/java/how-to-convert-byte-to-bufferedimage-in-java/