compress transparent png image to jpg give black background
I want white background instead of black
public static byte[] getBitMapBytes(Bitmap bmp, int quality) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, quality, stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
}
fos = new FileOutputStream(f);
fos.write(getBitMapBytes(compressedImage, 60));
Got the answer :
Bitmap newBitmap = Bitmap.createBitmap(image.getWidth(),
image.getHeight(), image.getConfig());
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.WHITE);
Rect dest = new Rect(0, 0, image.width, image.height);
Rect src = new Rect(0, 0, image.width, image.height);
canvas.drawBitmap(bmp, src, dest, null);
This is a normal behavior. Jpeg doesn't manage transparency.
You can use this kind of lib if you just want to reduce the size of the image:
http://objectplanet.com/pngencoder/ or online https://tinypng.com/
Related
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
I tried this but when I show the bitmap I can not see anything, what I want is to paint a white outline on the original image
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dog);
public byte[] myImagetoBytes(Bitmap bitmap){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
return stream.toByteArray();
}
byte[] bytes = myImagetoBytes();
bytes[0] = 1 & 0xff;
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
this.imageView.setImageBitmap(bitmap);
Not sure what your code is supposed to do, but if you want to draw over a bitmap, you should use Canvas. You create it with its constructor:
Canvas canvas = new Canvas(bitmap);
And then you can use it like this:
Paint paint = new Paint();
paint.setColor(Color.GRAY);
RectF ovalRect = new RectF(0, 0, 10, 10);
canvas.drawOval(ovalRect, paint);
I'm uploading a PNG with a transparent background to a Java server using the below code
byte[] imageData = Base64.decodeBase64(encodedImage);
ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
BufferedImage bufferedImage = ImageIO.read(bais);
BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(),
bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0, Color.OPAQUE, null);
Scene scene = sceneService.getScene(sceneId);
java.io.File file = new java.io.File(Constants.TEMP_DIR_PATH
+ UUID.randomUUID().toString() +".png");
ImageIO.write(newBufferedImage, "PNG", file);
I can't seem to set the background as transparent, it has to have a color?
Anyway to have a transparent background?
Use TYPE_INT_ARGB instead of TYPE_INT_RGB
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...
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.