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/
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'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());
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 have this method here, which converts an image to a byte array.
public byte[] imageToCompressedByteArray(Image image) throws IOException {
//load the image
String f = "C:\\Users\\mamed\\Documents\\NetBeansProjects\\Main\\src\\resources\\accept.png";
image = ImageIO.read(new FileInputStream(new File(f)));
// get image size
int width = image.getWidth(null);
int height = image.getHeight(null);
try {
int[] imageSource = new int[width * height];
PixelGrabber pg = new PixelGrabber(image, 0, 0, width, height, imageSource, 0, width);
pg.grabPixels();
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
GZIPOutputStream zippedStream = new GZIPOutputStream(byteStream);
ObjectOutputStream objectStream = new ObjectOutputStream(zippedStream);
objectStream.writeShort(width);
objectStream.writeShort(height);
objectStream.writeObject(imageSource);
objectStream.flush();
objectStream.close();
return byteStream.toByteArray();
}
catch (Exception e) {
throw new IOException("Error storing image in object: " + e);
}
}
However, i can't get this to work, i mean, it can't load the image and convert it, and i don't have an idea what the problem can be.
Are you sure the image path is correct and the loaded image is not corrupted image.
I not modified your code and I can see 1778416 byes its read from the image file.
I do not see anything wrong with the program. Maybe your image file is corrupted or image path is not correct.
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);