-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to compress image? #551
Comments
Of course there is. You can for example save it as JPEG (https://en.wikipedia.org/wiki/JPEG) using build-in Java You can save it directly into file: BufferedImage image = webcam.getImage();
ImageIO.write(image, "JPG", new File("image.jpg")); Or save it into BufferedImage image = webcam.getImage();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "JPG", baos);
byte[] data = baos.toByteArray(); It depends on what you would like to do with this compressed image later. If you want to specify your own JPEG compression rate (instead of using default one from https://stackoverflow.com/questions/17108234/setting-jpg-compression-level-with-imageio-in-java |
I hope I was able to answer your question. I'm closing this issue. |
I still want to get the bufferedimage data but not byte[ ]data ,is that work if I change the byte[ ] data I got into bufferedimage data like this? public BufferedImage getimageData(BufferedImage image) throws IOException {
BufferedImage Im;
BufferedImage im=null;
im = webcam.getImage();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(im, "JPG", baos);
byte[] data = baos.toByteArray();
ByteArrayInputStream stream = new ByteArrayInputStream(data);
image = ImageIO.read(stream);
return image;
} and if I change the webcam size like this is that means the data I get will change their size like this automatically? Webcam webcam ;
public WebcamNew (){
webcam = Webcam.getDefault();
webcam.setCustomViewSizes(new Dimension[] { new Dimension(1920, 1080) }); |
In regards to your questions:
Please read this: It may be a little outdated, but still helpful. |
I'm still wondering why would you want to convert |
I want to compress my image data ,and in the end I want to get an image date but not byte[ ] data .But I learned from internet that the image date can be compressed only if it changed into byte[ ].So I have no way but to do that .If there is any why can compress my image data directly ,I will not try that way . I hope you can understand my word , as I am a Chanese and poor in English. |
My work is to get BufferedImage image and ByteBuffer buf throw two ways . And I also need to compress the BufferedImage image I got into a short one that less than 20000 Bytes. I have tried lots of way buf all failed.this is what I wrote ,could you plese help me with it? public class WebcamNew implements webcam_interfacenew{
Webcam webcam ;
public WebcamNew (){
webcam = Webcam.getDefault();
webcam.setViewSize(new Dimension(120, 160));
}
public BufferedImage getimageData(BufferedImage image) throws IOException {
BufferedImage im=null;
im = webcam.getImage();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(im, "JPG", baos);
byte[] data = baos.toByteArray();
ByteArrayInputStream stream = new ByteArrayInputStream(data);
image = ImageIO.read(stream);
return image;
}
public ByteBuffer getbufData(ByteBuffer buf) {
buf = WebcamUtils.getImageByteBuffer(webcam, "JPG");
return buf;
}
} thank you very very much! |
Ok, @turboleee, please read this whole post and ask if you do not understand what I wrote. To make it clear - the When you convert it back from The byte[] bytes = ...
ByteBuffer buffer = ByteBuffer.wrap(bytes); The only way to make // 640x480
BufferedImage original = webcam.getImage();
// 320x240
BufferedImage smaller = original.getScaledInstance(320, 240, Image.SCALE_SMOOTH); If you need to calculate how much memory BufferedImage bi = webcam.getImage();
int howManyBytes = bi.getWidth() * bi.getHeight() * 3;
System.out.println("This image consume "+ howManyBytes + " bytes of memory"); (for example, not compressed image with size 640x480 will consume 921600 bytes in memory) Below is a code I wrote to compress image with any resolution into import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.MemoryCacheImageOutputStream;
/**
* This class will save {@link BufferedImage} into a byte array and compress it so the number of
* compressed bytes is not higher than a given maximum level. It is not thread-safe.
*
* @author Bartosz Firyn (sarxos)
*/
public class AdaptiveSizeWriter {
private final int max;
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
private float q = 1f; // 1f = 100% quality, at the beginning
private int w = 0;
private int h = 0;
public AdaptiveSizeWriter(int size) {
this.max = size;
}
public byte[] write(BufferedImage bi) {
final int iw = bi.getWidth();
final int ih = bi.getHeight();
if (w != iw || h != ih) {
w = iw;
h = ih;
q = 1f;
}
// loop and try to compress until compressed image bytes array is not longer than a given
// maximum value, reduce quality by 25% in every step
int size = 0;
do {
size = compress(bi, q);
if (size > max) {
q *= 0.75;
}
} while (size > max);
return baos.toByteArray();
}
/**
* Compress {@link BufferedImage} with a given quality into byte array.
*
* @param bi the {@link BufferedImage} to compres into byte array
* @param quality the compressed image quality (1 = 100%, 0.5 = 50%, 0.1 = 10%, etc)
* @return The size of compressed data (number of bytes)
*/
private int compress(BufferedImage bi, float quality) {
baos.reset();
final JPEGImageWriteParam params = new JPEGImageWriteParam(null);
params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
params.setCompressionQuality(quality);
try (MemoryCacheImageOutputStream mcios = new MemoryCacheImageOutputStream(baos)) {
final ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
writer.setOutput(mcios);
writer.write(null, new IIOImage(bi, null, null), params);
} catch (IOException e) {
throw new IllegalStateException(e);
}
final int size = baos.size();
System.out.printf("Quality %.2f, resolution %dx%d, bytes count = %d\n", quality, bi.getWidth(), bi.getHeight(), size);
return size;
}
} How to use it: import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import com.github.sarxos.webcam.Webcam;
public class ExampleWebcam {
public static void main(String[] args) throws IOException {
final Dimension resolution = new Dimension(1280, 720); // HD720p
final Webcam webcam = Webcam.getDefault();
webcam.setCustomViewSizes(new Dimension[] { resolution });
webcam.setViewSize(resolution);
webcam.open();
final BufferedImage bi = webcam.getImage();
final AdaptiveSizeWriter writer = new AdaptiveSizeWriter(20000); // max number of bytes
final byte[] data = writer.write(bi);
try (FileOutputStream fos = new FileOutputStream(new File("example.jpg"))) {
fos.write(data);
}
}
} I tested it with two resolutions:
Result for HD720p - 1280x720 (9 cycles, 10% quality, 19706 bytes): Result for VGA - 640x480 (3 cycles, 56% quality, 18678 bytes): |
Thank you very much for answer me so particularly ! And I don't know how to express my appreciation to you. |
Could you tell me is there any way to compress image data that I got from wecam?
The text was updated successfully, but these errors were encountered: