Loss of color when resizing images - java

I am using this method to change image size:
private File resize(double scale, File file) throws IOException {
double scaledSize = targetSize * scale;
BufferedImage scaledImage = Scalr.resize(sourceImage, (int) scaledSize);
Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName(fileExt);
ImageWriter writer = iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(1);
FileImageOutputStream output = new FileImageOutputStream(file);
writer.setOutput(output);
IIOImage image = new IIOImage(scaledImage, null, null);
writer.write(null, image, iwp);
writer.dispose();
return file;
}
It seems images lose color depth. How can I set same color depth as source image?

Related

How to resolve: javax.imageio.IIOException: Bogus input colorspace

I have a function generateImageOutput below to write BufferedImage to jpeg file.
public boolean generateImageOutput(BufferedImage image, String filename){
//The image is written to the file by the writer
File file = new File( projectFolder+"/data/"+filename+".jpg");
//Iterator containing all ImageWriter (JPEG)
Iterator encoder = ImageIO.getImageWritersByFormatName("JPEG");
ImageWriter writer = (ImageWriter) encoder.next();
//Compression parameter (best quality)
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(1.0f);
//Try to write the image
try{
ImageOutputStream outputStream = ImageIO.createImageOutputStream(file);
writer.setOutput(outputStream);
writer.write(null, new IIOImage(image, null, null), param);
outputStream.flush();
writer.dispose();
outputStream.close();
}catch(IOException e){
e.printStackTrace();
System.out.println(e.toString());
return false;
}
return true;
}
It works for some, but it fails for a BufferedImage converted from base64 string:
String encodedString = JSON.parseObject(string).getString("image");
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
ByteArrayInputStream bis = new ByteArrayInputStream(decodedBytes);
buffered_image = ImageIO.read(bis);
When writing the above buffered_image to jpeg using generateImageOutput, it raises exception :
javax.imageio.IIOException: Bogus input colorspace
at java.desktop/com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeImage(Native Method)
at java.desktop/com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeOnThread(JPEGImageWriter.java:1007)
at java.desktop/com.sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:371)
The string encodedString has no issue, I have sucessfully converted it to an image online.
How can I resolve the exception ?
According to #J.doe Alpha channel must be remove. I have a code that removes the Alpha channel. The code below was to determine whether or not the image has alpha channel. If the image has alpha channel it will create an image without alpha channel.
private static BufferedImage removeAlphaChannel(BufferedImage img) {
if (!img.getColorModel().hasAlpha()) {
return img;
}
BufferedImage target = createImage(img.getWidth(), img.getHeight(), false);
Graphics2D g = target.createGraphics();
// g.setColor(new Color(color, false));
g.fillRect(0, 0, img.getWidth(), img.getHeight());
g.drawImage(img, 0, 0, null);
g.dispose();
return target;
}
private static BufferedImage createImage(int width, int height, boolean hasAlpha) {
return new BufferedImage(width, height, hasAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
}
Finally I find that the reason is the image has an ALPHA channel.
Looks like JPEG doesn't handle the alpha channel correctly in this context. For me saving the image as PNG did the trick.

Java Image Compression : colour changes

I am using below code for reducing image size. It reduces size from 1MB to 250 KB. Its fine but it changes image colour.
File input = new File("ImageTOCompress.jpg");
BufferedImage image = ImageIO.read(input);
File compressedImageFile = new File("CompressedImage.jpg");
OutputStream os =new FileOutputStream(compressedImageFile);
Iterator<ImageWriter>writers = ImageIO.getImageWritersByFormatName("jpg");
ImageWriter writer = (ImageWriter) writers.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(os);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(0.05f);
writer.write(null, new IIOImage(image, null, null), param);
os.close();
ios.close();
writer.dispose();
Please help me to maintain image colour as it is...Thanks!!!

Reducing Image Size and Saving it in MySQL DB with Java

I know that we can save image in mysql using BLOB Data Type and The Code i have used it as follows,
JFileChooser fc = new JFileChooser();
fc.setFileFilter(new JPEGImageFileFilter());
int res = fc.showOpenDialog(null);
try {
if (res == JFileChooser.APPROVE_OPTION) {
File image = new File(fc.getSelectedFile().getPath());
FileInputStream fis = new FileInputStream ( image );
String sql="insert into imgtst (username,image) values (?, ?)";
pst=con.prepareStatement(sql);
pst.setString(1, user);
pst.setBinaryStream (2, fis, (int) file.length() );
} else {
JOptionPane.showMessageDialog(null, "you must select image",
"Abortin", JOptionPane.WARNING_MESSAGE);
}
} catch (Exception ioException) {
e.printStackTrace();
}
Now What do i need to make sure the file size which is saving into the database should not be more than 100 KB if its more than that size i need some method to compress the size of an image to be 100 KB.Kindly give your valuable suggestions.
Try this
public static BufferedImage resizeImage(Image image, int width, int height) {
final BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
final Graphics2D graphics2D = bufferedImage.createGraphics();
graphics2D.setComposite(AlphaComposite.Src);
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.drawImage(image, 0, 0, width, height, null);
graphics2D.dispose();
return bufferedImage;
}
maybe you can try compress the image first before insert it into database.
this is the example i got for compressing the image :
File imageFile = new File("myimage.jpg");
File compressedImageFile = new File("myimage_compressed.jpg");
InputStream is = new FileInputStream(imageFile);
OutputStream os = new FileOutputStream(compressedImageFile);
float quality = 0.5f;
// create a BufferedImage as the result of decoding the supplied InputStream
BufferedImage image = ImageIO.read(is);
// get all image writers for JPG format
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
if (!writers.hasNext())
throw new IllegalStateException("No writers found");
ImageWriter writer = (ImageWriter) writers.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(os);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
// compress to a given quality
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
// appends a complete image stream containing a single image and
//associated stream and image metadata and thumbnails to the output
writer.write(null, new IIOImage(image, null, null), param);
// close all streams
is.close();
os.close();
ios.close();
writer.dispose();

png file turn all black when compress to jpeg. Is it because PNG is lossless?

I have a piece of code that compress an jpg image with a certain quality, but when the image is png type, they all turn black. Any idea why and how to fix it? here is my code.
public void compressImage(String filename, ServletContext servletContext) {
//You first need to enumerate the image writers that are available to jpg
Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
//Then, choose the first image writer available
ImageWriter writer = (ImageWriter) iter.next();
//instantiate an ImageWriteParam object with default compression options
ImageWriteParam iwp = writer.getDefaultWriteParam();
//Set the compression quality
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(0.5f);
try {
BufferedImage img = ImageIO.read(new File(filename));
String destPath = "/Users/KingdomHeart/resources/scholar/compress/compress.jpg";
File file = new File(destPath);
FileImageOutputStream output = new FileImageOutputStream(file);
writer.setOutput(output);
IIOImage image = new IIOImage(img, null, null);
writer.write(null, image, iwp);
writer.dispose();
}catch(IOException e){
}
}
This might have the answers you're looking for: Converting transparent gif / png to jpeg using java
The issue is likely that you're working with a PNG that has some transparency in it.

ColorConvertOp increasing the size of the target image. Is there a way to reduce the size when we go from color to black and white?

I am using java and the following code. Is there a way to use RenderingHints to accomplish this?
try {
sourceImage = ImageIO.read(new File("images.jpg"));
BufferedImage dstImage = null;
ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp op = new ColorConvertOp(colorSpace, null);
dstImage = op.filter(sourceImage, null);
ImageIO.write(dstImage, "jpeg", new File("output.jpg"));
System.out.println("processing complete");
} catch (IOException e) {
e.printStackTrace();
}
I got this working using ImageWriteParam.setCompressionQuality
Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = (ImageWriter)iter.next();
// instantiate an ImageWriteParam object with default compression options
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(0.5f); // an integer between 0 and 1
// 1 specifies minimum compression and maximum quality
File file = new File("output.jpg");
FileImageOutputStream output = new FileImageOutputStream(file);
writer.setOutput(output);
IIOImage image = new IIOImage(dstImage, null, null);
writer.write(null, image, iwp);
writer.dispose();

Categories

Resources