使用GifSequenceWriter-Java

时间:2018-07-03 23:11:23

标签: java gif bufferedimage steganography lsb

我正试图在.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? 预先感谢。

1 个答案:

答案 0 :(得分:0)

使用调色板图像(GifSequenceWriterBufferedImage.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);

...作者将根据您的实际图像数据自动创建调色板。

The animated GIF created with the code above


也可以修复GifSequenceWriter,接受ImageTypeSpecifier而不是int imageType,但是,这仅在所有框架都使用相同的调色板时才有效,我认为:< / p>

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);