Java: How To Convert Image to Byte[] - java

I'm having an image in Database in bytearray format. I want to display on browser. I don't know how to write Image using OutputStream. Here is my code.
byte[] imageInBytes = (byte[]) obj; // from Database
InputStream in = new ByteArrayInputStream(imageInBytes);
Image img = ImageIO.read(in).getScaledInstance(50, -1, Image.SCALE_SMOOTH);
OutputStream o = resp.getOutputStream(); // HttpServletResponse
o.write(imgByte);

You may try something like this:
File f=new File("image.jpg");
BufferedImage o=ImageIO.read(f);
ByteArrayOutputStream b=new ByteArrayOutputStream();
ImageIO.write(o, "jpg", b);
byte[] img=b.toByteArray();

You have to set the content type of the response to be an image type that you are sending.
Suppose your image was stored when it was a jpeg. then,
OutputStream o = resp.getOutputStream(); // HttpServletResponse
o.setContentType("image/jpeg");
o.write(img.getBytes() /* imgByte */);
would send the browser an image. ( The browser understands from the header information that the following information you just sent it, is a jpeg image. )

You could try using ImageIO.write...
ImageIO.write(img, "jpg", o);
But this will require you to use BufferedImage when reading...
BufferedImage img = ImageIO.read(in);
You could then use AffineTransform to scale the image...
BufferedImage scaled = new BufferedImage(img.getWidth() / 2, img.getHeight() / 2, img.getType());
Graphics2D g2d = scaled.createGraphics();
g2d.setTransform(AffineTransform.getScaledInstance(0.5, 0.5));
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
img = scaled;
This, obviously, only scales the image by 50%, so you'll need to calculate the required scaling factor based on the original size of the image against your desired size...
Take a look at Java: maintaining aspect ratio of JPanel background image for some ideas on scaling images...

Related

How can I convert fingerprint jpg to WSQ use JMRTD WSQEncoder.encode

I'm using JMRTD library (https://github.com/E3V3A/JMRTD/tree/master/wsq_imageio) to encode jpg to WSQ. I set Bitmap by manually instead of decode from WSQ file.
BufferedImage bufferedImage = ImageIO.read(fileInput.getInputStream());
WritableRaster raster = bufferedImage.getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
Bitmap bitmap = new Bitmap(data.getData(), width, height, ppi, depth, lossyflag);
OutputStream outputStream = new FileOutputStream("c.wsq");
String commentText = "";
WSQEncoder.encode(outputStream, bitmap, bitrate, commentText);
Here is my original picture jpg:
And below is my result WSQ file:
How can I fix it. Many thanks!
I resolved this problem, here is my code for convert jpg, png to wsq format:
// 1. Read files to BufferedImage for get width, height. Convert Bit depth to 8-gray
BufferedImage bufferedImage = ImageIO.read(fileInput.getInputStream());
// 2. Convert Bit depth to 8-gray (This is what i had to do to solve this problem)
BufferedImage img = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
Graphics g = img.getGraphics();
g.drawImage(bufferedImage, 0, 0, null);
g.dispose();
// 3. Convert file format to byte[] and convert to type Bitmap
WritableRaster raster = img.getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
Bitmap bitmap = new Bitmap(data.getData(), bufferedImage.getWidth(), bufferedImage.getHeight(), 500, 8, 1);
// 4. Create file wsq
OutputStream outputStream = new FileOutputStream("c.wsq");
double bitrate = 0.75f;
String commentText = "";
// 5. Write the input file to the generated wsq file
WSQEncoder.encode(outputStream, bitmap, bitrate, commentText);
outputStream.close();
Hope help you # Dan Ortega

Converting a color image to grayscale is showing black image in java

I am trying to convert an image to gray scale image using Java. The problem here is, when I am trying to save that image after converting into gray scale it is showing a black image. I am little unaware of this image conversions. I would like to know why it is not working, and your answers will help me in my project. Thank you.
BufferedImage image = ImageIO.read(fileContent);
File outputFile = new File(date1);
ImageIO.write(image1, "png", outputFile);
(This is the color image obtained from html page, and it is working properly. And when I am trying to display/save this image, color image is visible. But the problem arises when the below code is used to convert color image to gray scale image.)
BufferedImage image1 = new BufferedImage(width, height,BufferedImage.TYPE_BYTE_GRAY);
Graphics graphics = image1.getGraphics();
graphics.drawImage(image, 0, 0, null);
graphics.dispose();
File outputFile = new File(date1);
ImageIO.write(image1, "png", outputFile);
There are color space conversion issues. You can manually convert each pixel of the output image to grayscale and set the pixels of the output image this way:
int gray = red * 0.299 + green * 0.587 + blue * 0.114
or use the ColorConvertOp class to do the conversion for you:
BufferedImage in = ImageIO.read(inputFile);
BufferedImage out = new BufferedImage(in.getWidth(), in.getHeight(), BufferedImage.TYPE_INT_ARGB);
ColorConvertOp op = new ColorConvertOp(in.getColorModel().getColorSpace(), ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
op.filter(in, out);
ImageIO.write(out, "png", outputFile);

Byte[] to BufferedImage in java

I have a problem with showing a picture from the database, the database saves the picture in blob, when i pick up the data the blob passes to Byte[], so after that i do that to show the image, why didnt work?
Select_1 xp = new Select_1();
byte[] img=xp.Select_1(username);
InputStream in = new ByteArrayInputStream(img);
BufferedImage image = ImageIO.read(in);
BufferedImage resizedImage=resize(image,204,204);
ImageIcon icon=new ImageIcon(resizedImage);
lblavatar.setIcon(icon);
Edit according to the comment:
Originally, the image was written using the following methods:
blob = (Blob) connect.createBlob();
ImageIcon ii = new ImageIcon(ficheiro);
ObjectOutputStream oos;
oos = new ObjectOutputStream(blob.setBinaryStream(1));
oos.writeObject(ii);
oos.close();
psInsert.setBlob(4, blob);
You are not serialzing a BufferedImage, but an ImageIcon.
In order to create an image from the blob data, you have to do "the opposite" of what you have been doing to create the blob. In this case, you'll have to do something along the lines of
byte[] img=xp.Select_1(username);
InputStream in = new ByteArrayInputStream(img);
ObjectInputStream ois = new ObjectInputStream(in);
ImageIcon imageIcon = (ImageIcon)ois.readObject();
Now, you have an ImageIcon, from which you can obtain the Image. For many cases, this image can be used directly. If you really need a BufferedImage, then you can do
BufferedImage bi = new BufferedImage(204,204,BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
g.drawImage(imageIcon.getImage(), 0, 0, 204, 204, null);
g.dispose();
Then the buffered image will contain your image (already scaled to the desired target size of 204,204 in this case).
In any case, you should consider to not store the image as a serialized ImageIcon. Instead, you should write your image into a byte array as a PNG or JPG file, and store the resulting byte array as the blob in the database, as, for example, shown in Java: BufferedImage to byte array and back

Java display base 64 byte array in jsp

I have a class called Graphic that creates a new BufferedImage, draws a new Graphics2D and returns this image as base64 encoded String:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Draw background
g2.setColor(Color.decode("#FFFFFF"));
g2.fillRect(0, 0, grafikBreite, grafikHoehe);
g2.setColor(Color.decode("#000000"));
// Draw some rectangles and other stuff...
drawStuff(g2);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] imageInByte = {};
try {
JPEGImageEncoder j = new JPEGImageEncoderImpl(baos);
j.encode(image);
imageInByte = baos.toByteArray();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
return javax.xml.bind.DatatypeConverter.printBase64Binary(imageInByte);
In my jsp-File I want to display this image using, where graphic is the previously created base64 byte array:
<img src="data:image/jpg;base64,<c:out value="${graphic}"/>"/>
The image is displayed, but the problem is that the image has red background and the other colors used are also wrong. If I save the created base64 string as jpeg-File on hard disk, all colors are displayed correctly.
Has someone an idea why HTML displays the image with strange colors?
Thanks for help
First a bit cleaning up:
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, grafikBreite, grafikHoehe);
g2.setColor(Color.BLACK);
drawStuff(g2);
g2.dispose(); // TODO
Dispose after createGraphics.
Then one could try the more generic, portable ImageIO class. The parametrising for antialiasing and such goes a bit different, but then JPEG is a lossy format anyway. Just to try a different angle.
ImageIO.write(image, "jpg", baos);
baos.close();
imageInByte = baos.toByteArray();
And then I did the closing first. (It has no effect by javadoc.)
One could try .png and a another type, ABGR.
I think ImageIO does the trick, or your code with ABGR.

encoding and decoding in JPG images in Android

I am creating an application over Android where I need to manipulate my JPG files. I am not getting much of header information for JPG format so for that I am converting it to Bitmap, manipulated the pixel values in bitmap and then again convert it back to JPG.
Here what problem I am facing is- after manipulating only some pixels of bitmap and
converting it back to JPG, I do not get the same set of pixels I got earlier (for those pixels which I did not manipulate). I am getting the same image as the original in the new image. But when I check new image pixels values for decoding, the untouched pixels are different...
File imagefile = new File(filepath);
FileInputStream fis = new FileInputStream(imagefile);
Bitmap bi = BitmapFactory.decodeStream(fis);
int intArray[];
bi=bi.copy(Bitmap.Config.ARGB_8888,true);
intArray = new int[bi.getWidth()*bi.getHeight()];
bi.getPixels(intArray, 0, bi.getWidth(), 0, 0, bi.getWidth(), bi.getHeight());
int newArray[] = encodeImage(msgbytes,intArray,mbytes); // method where i am manipulating my pixel values
// converting the bitmap data back to JPG file
bi = Bitmap.createBitmap(newArray, bi.getWidth(), bi.getHeight(), Bitmap.Config.ARGB_8888);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bi.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();
Bitmap bitmapimage = BitmapFactory.decodeByteArray(data, 0, data.length);
String filepath = "/sdcard/image/new2.jpg";
File imagefile = new File(filepath);
FileOutputStream fos = new FileOutputStream(imagefile);
bitmapimage.compress(CompressFormat.JPEG, 100, fos);
Help me if I am wrong somewhere or whether I should use some other method to manipulate JPG pixel values...
JPEG is an image format that is usually based on lossy compression. That means that some information that is not important for the human eye is thrown away to further shrink the file size. Try to save your image as a PNG (a lossless format).
Be careful with using
Bitmap bi = BitmapFactory.decodeStream(fis);
bi = bi.copy(Bitmap.Config.ARGB_8888, true);
At the point where you have the first bi you may have already lost a lot of information, instead try using BitmapFactory.Options to force 8888 (which is the default too):
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inDither = false;
Bitmap bi = BitmapFactory.decodeStream(fis, options);
If you stay with copy you should still recycle() the one that you throw away.

Categories