|
|
@@ -11,11 +11,15 @@ import java.nio.channels.FileChannel;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.List;
|
|
|
+import javax.imageio.IIOImage;
|
|
|
import javax.imageio.ImageIO;
|
|
|
+import javax.imageio.ImageWriteParam;
|
|
|
+import javax.imageio.ImageWriter;
|
|
|
+import javax.imageio.stream.ImageOutputStream;
|
|
|
|
|
|
/**
|
|
|
* Released under BSD License
|
|
|
- * @author monceaux, normenhansen
|
|
|
+ * @author monceaux, normenhansen, entrusC
|
|
|
*/
|
|
|
public class MjpegFileWriter {
|
|
|
|
|
|
@@ -56,7 +60,11 @@ public class MjpegFileWriter {
|
|
|
}
|
|
|
|
|
|
public void addImage(Image image) throws Exception {
|
|
|
- addImage(writeImageToBytes(image));
|
|
|
+ addImage(image, 0.8f);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void addImage(Image image, float quality) throws Exception {
|
|
|
+ addImage(writeImageToBytes(image, quality));
|
|
|
}
|
|
|
|
|
|
public void addImage(byte[] imagedata) throws Exception {
|
|
|
@@ -79,18 +87,29 @@ public class MjpegFileWriter {
|
|
|
}
|
|
|
}
|
|
|
imagedata = null;
|
|
|
+
|
|
|
+ numFrames++; //add a frame
|
|
|
}
|
|
|
|
|
|
public void finishAVI() throws Exception {
|
|
|
byte[] indexlistBytes = indexlist.toBytes();
|
|
|
aviOutput.write(indexlistBytes);
|
|
|
aviOutput.close();
|
|
|
- long size = aviFile.length();
|
|
|
+ int fileSize = (int)aviFile.length();
|
|
|
+ int listSize = (int) (fileSize - 8 - aviMovieOffset - indexlistBytes.length);
|
|
|
+
|
|
|
RandomAccessFile raf = new RandomAccessFile(aviFile, "rw");
|
|
|
- raf.seek(4);
|
|
|
- raf.write(intBytes(swapInt((int) size - 8)));
|
|
|
- raf.seek(aviMovieOffset + 4);
|
|
|
- raf.write(intBytes(swapInt((int) (size - 8 - aviMovieOffset - indexlistBytes.length))));
|
|
|
+
|
|
|
+ //add header and length by writing the headers again
|
|
|
+ //with the now available information
|
|
|
+ raf.write(new RIFFHeader(fileSize).toBytes());
|
|
|
+ raf.write(new AVIMainHeader().toBytes());
|
|
|
+ raf.write(new AVIStreamList().toBytes());
|
|
|
+ raf.write(new AVIStreamHeader().toBytes());
|
|
|
+ raf.write(new AVIStreamFormat().toBytes());
|
|
|
+ raf.write(new AVIJunk().toBytes());
|
|
|
+ raf.write(new AVIMovieList(listSize).toBytes());
|
|
|
+
|
|
|
raf.close();
|
|
|
}
|
|
|
|
|
|
@@ -142,6 +161,10 @@ public class MjpegFileWriter {
|
|
|
|
|
|
public RIFFHeader() {
|
|
|
}
|
|
|
+
|
|
|
+ public RIFFHeader(int fileSize) {
|
|
|
+ this.fileSize = fileSize;
|
|
|
+ }
|
|
|
|
|
|
public byte[] toBytes() throws Exception {
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
@@ -382,6 +405,10 @@ public class MjpegFileWriter {
|
|
|
public AVIMovieList() {
|
|
|
}
|
|
|
|
|
|
+ public AVIMovieList(int listSize) {
|
|
|
+ this.listSize = listSize;
|
|
|
+ }
|
|
|
+
|
|
|
public byte[] toBytes() throws Exception {
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
baos.write(fcc);
|
|
|
@@ -473,7 +500,7 @@ public class MjpegFileWriter {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public byte[] writeImageToBytes(Image image) throws Exception {
|
|
|
+ public byte[] writeImageToBytes(Image image, float quality) throws Exception {
|
|
|
BufferedImage bi;
|
|
|
if (image instanceof BufferedImage && ((BufferedImage) image).getType() == BufferedImage.TYPE_INT_RGB) {
|
|
|
bi = (BufferedImage) image;
|
|
|
@@ -483,7 +510,17 @@ public class MjpegFileWriter {
|
|
|
g.drawImage(image, 0, 0, width, height, null);
|
|
|
}
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
- ImageIO.write(bi, "jpg", baos);
|
|
|
+
|
|
|
+ ImageWriter imgWrtr = ImageIO.getImageWritersByFormatName("jpg").next();
|
|
|
+ ImageOutputStream imgOutStrm = ImageIO.createImageOutputStream(baos);
|
|
|
+ imgWrtr.setOutput(imgOutStrm);
|
|
|
+
|
|
|
+ ImageWriteParam jpgWrtPrm = imgWrtr.getDefaultWriteParam();
|
|
|
+ jpgWrtPrm.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
|
|
+ jpgWrtPrm.setCompressionQuality(quality);
|
|
|
+ imgWrtr.write(null, new IIOImage(bi, null, null), jpgWrtPrm);
|
|
|
+ imgOutStrm.close();
|
|
|
+
|
|
|
baos.close();
|
|
|
return baos.toByteArray();
|
|
|
}
|