Byte[] to BufferedImage in java - 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

Related

Change in color while using ImageIO.read()

I am trying to read images from external directory and for that I am using
bufferedImage image=ImageIO.read(new File(imagefile));
jlabel.seticon(new imageicon(image));
and getting a drastic change in colors. I tried many other things like:
bufferedImage image=ImageIO.read(new File(imagefile));
bufferedImage img=new bufferedImage(image.getWidth(),image.getHeight(),bufferedImage.TYPE_INT_RGB);
and I tried:
img.setData(image.getData();
jlabel.seticon(new imageicon(image));
and I tried:
Iterator readers = ImageIO.getImageReadersByFormatName("JPEG");
ImageReader reader = null;
while(readers.hasNext()) {
reader = (ImageReader)readers.next();
if(reader.canReadRaster()) {
break;
}
}
ImageInputStream input = ImageIO.createImageInputStream(f);
reader.setInput(input);
Raster raster = reader.readRaster(0, null);
BufferedImage bi = new BufferedImage(raster.getWidth(), raster.getHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
bi.getRaster().setRect(raster);
but result are still same
http://i.stack.imgur.com/jNVm0.jpg
Here is an example of the issue:
The minimal code for viewing is:
bufferedImage image=ImageIO.read(new File(imagefile));
jlabel.seticon(new imageicon(image));
lbitem.setIcon(im);
and for storing
File f = new File(s);
long size=f.length();
FileInputStream fis1=new FileInputStream(f);
FileOutputStream fos2=new FileOutputStream("src/image/"+tfpn.getText()+".jpg");
byte b[]=new byte[1000];
int r=0;
long count=0;
while(true)
{
r=fis1.read(b,0,1000);
fos2.write(b,0,1000);
count = count+r;
if(count==size)
break;
System.out.println(count);
}
What could be causing the bad colors?
This problem is cause by a mismatch between reading/writing (creating/using) an image
that contains alpha (transparency) but you are expecting it to contain no alpha (or the inverse).
For example, if your image is BufferedImage.TYPE_4BYTE_ABGR and you output it
to a file type that does not support alpha (transparency) , or you writer does not
support alpha, it will look like your sample after reading and displaying it.
Use type PNG (supports alpha channel) not JPG (does not support alpha channel)

Java: How To Convert Image to Byte[]

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...

How to make custom Tiles in android google maps

Android's Google Maps api v2 provides a TileOverlay to which TileProviders can be added. A TileProvider will generate a Tile object given the lat, long, and depth. In order to make a tile, one must give it width (easy), height (easy), and an image represented as a byte array (confusing me). If I wanted to 'draw' a simple object and then turn it into a byte array, how would I do this?
For instance I am looking for something that looks like
Canvas canvas = new canvas();
...
canvas.drawRect(); //Or something like this (just an example)
...
byte[] bytes = canvas.SomeConversionFunctionOrProcessThatIDontKnow();
return new Tile(1,1,bytes);
public byte[] getByteArray (String image) throws IOException {
File yourImg = new File(image);
BufferedImage bufferedImage = ImageIO.read(yourImg);
WritableRaster wRaster = bufferedImage .getRaster();
DataBufferByte data = (DataBufferByte) wRaster.getDataBuffer();
return data.getData();
}
This should do the trick ; )
Tile#data should be compressed image data in one of the supported image formats. In other words, the raw contents of an image file. If you already have a decoded Bitmap, use Bitmap#compress(...) to write it to a ByteArrayOutputStream, then get the byte[] from that.
Bitmap bitmap = Bitmap.createBitmap(TILE_DIMENSION, TILE_DIMENSION,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
......
//draw something
......
Tile tile = convertBitmap(bitmap);
bitmap.recycle();
return tile;
}
private Tile convertBitmap(Bitmap bitmap){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] bitmapData = stream.toByteArray();
return new Tile(TILE_DIMENSION, TILE_DIMENSION, bitmapData);
}

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.

Getting an in-memory representation of the JPEG rendering of an Image

I need to know how to get an array of bytes from a loaded image, in java. BufferedImage seems not to supply any methods that produce an array of bytes, so what do I use?
BufferedImage bufferedImage; //assumed that you have created it already
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage,"jpg", byteStream);
byte[] byteArray = byteStream.toByteArray();

Categories