我正在尝试为隐写术项目隐藏.gif内的消息。
我已经将输入的gif转换为BufferedImages的ArrayList,并应用了隐写算法。
但是,我遇到了将BufferedImages的ArrayList转换回.gif的问题。
在从原始gif图像元数据获取帧之间的原始延迟之后,我使用了这个GifSequenceWriter类将BufferedImages数组转换为新的.gif。
File encoded_img = new File("output.gif");
ImageOutputStream output = new FileImageOutputStream(encoded_img);
GifSequenceWriter writer = new GifSequenceWriter(output, frames.get(0).getType(), delayTimeMS, true);
writer.writeToSequence(frames.get(0));
for(int k=1; k<frames.size()-1; k++) {
writer.writeToSequence(frames.get(k));
}
writer.close();
output.close();
但是,生成的.gif看起来确实很糟糕,并且我保存了带有或不带有隐写算法的单个帧,它们看起来不错。您可以查看原始图像,保存的10个帧以及生成的.gif here的示例。
有没有更好的方法来在Java中创建.gifs?
提前致谢。
最佳答案
使用调色板图像(GifSequenceWriter
和BufferedImage.TYPE_BYTE_INDEXED
)时,IndexColorModel
存在问题。这将基于默认的216调色板(web safe palette)创建元数据,该调色板明显不同于图像中的颜色。GifSequenceWriter
中有问题的行:
ImageTypeSpecifier imageTypeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(imageType);
imageMetaData = gifWriter.getDefaultImageMetadata(imageTypeSpecifier, imageWriteParam);
而是,元数据应基于图像索引颜色模型中的调色板。但好消息是,没有它,它会很好地工作。
您可以简单地使用:
GifSequenceWriter writer = new GifSequenceWriter(output, BufferedImage.TYPE_INT_ARGB, delayTimeMS, true);
...作者将根据您的实际图像数据自动创建调色板。
也可以修复
GifSequenceWriter
,接受ImageTypeSpecifier
而不是int imageType
,但是,这仅在所有框架都使用相同的调色板时才有效,我认为:public GifSequenceWriter(
ImageOutputStream outputStream,
ImageTypeSpecifier imageTypeSpecifier,
int timeBetweenFramesMS,
boolean loopContinuously) throws IIOException, IOException {
// my method to create a writer
gifWriter = getWriter();
imageWriteParam = gifWriter.getDefaultWriteParam();
imageMetaData = gifWriter.getDefaultImageMetadata(imageTypeSpecifier, imageWriteParam);
// ... rest of the method unchanged.
用法:
ColorModel cm = firstImage.getColorModel();
ImageTypeSpecifier imageType = new ImageTypeSpecifier(cm, cm.createCompatibleSampleModel(1, 1));
GifSequenceWriter writer = new GifSequenceWriter(output, imageType, delayTimeMS, true);