【问题标题】:Android pngj with Bitmap and custom header带有位图和自定义标题的 Android pngj
【发布时间】:2016-03-13 05:48:35
【问题描述】:

我正在尝试使用 PNGJ 库添加自定义元数据,tEXT

在 Android 中,我执行以下操作

    Bitmap output = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    output.compress(Bitmap.CompressFormat.PNG, 100, stream);

有没有可能在PNGJ中做这样的事情

     Bitmap output = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
     //Add custom meta-data here
     //Save the PNG file with PNGJ here using output

到目前为止,我所做的就是这样,

Bitmap output = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
ImageInfo imi = new ImageInfo(bitmap.getWidth(), bitmap.getHeight(), 16, true); 
PngWriter png = new PngWriter(stream, imi);

png.getMetadata().setDpi(100.0);
png.getMetadata().setTimeNow(0);
png.getMetadata().setText(PngChunkTextVar.KEY_Title, "testing");
png.getMetadata().setText("Custom Key", "some text");
//Not sure how to connect the bitmap above to the PngWriter here  

第二种方法,稍后添加标签

public void addTag(File orig, File dest, boolean overwrite) {
    PngReader pngr = new PngReader(orig);
    PngWriter pngw = new PngWriter(dest, pngr.imgInfo, overwrite);
    pngw.copyChunksFrom(pngr.getChunksList(), ChunkCopyBehaviour.COPY_ALL_SAFE);
    pngw.getMetadata().setText("appkey", "I'm value", true, false);

    for (int row = 0; row < pngr.imgInfo.rows; row++) {
        ImageLineInt line = (ImageLineInt) pngr.readRow(row);
         pngw.writeRow(line, row);
    }
    pngr.end();
    pngw.end();
}

现在,当我试图用它来获得它时,我什么也没得到

PngReader reader  = new PngReader(new File(fileName1));

 Log.d("pngkey", "value is: " + reader .getMetadata().getTxtForKey("appkey"));

请注意,当我使用以下内容检查 png 时,我确实看到添加了新标签

pngcheck -c -v -t image.png

【问题讨论】:

    标签: android png metadata


    【解决方案1】:

    您必须自己进行转换。 最简单(如果不是最有效)的方法是:

    • 实例化ImageLineInt(或ImageLineByte)
    • 循环遍历位图的每一行,调用 Bitmap.getPixels() 将行中的像素存储为整数 (Color),并在 int[] 数组中
    • 使用 ImageLineHelper.setPixelRGBA8() 逐像素填充 ImageLine,(或手动)
    • 将 ImageLine 写入 png。

    基本上就是这样。您必须首先确定是否使用 Alpha 生成图像(似乎是)。另外,我不确定您为什么将 16 用于位深度,它几乎肯定应该是 8。如果您需要更多帮助,请告诉我。


    更新: 关于您修改后的问题:

    PngReader reader  = new PngReader(new File(fileName1));
    String txt= reader.getMetadata().getTxtForKey("appkey");
    

    如果将元数据放在像素数据(IDAT 块)之后,它将找不到元数据。那是因为,那时,您还没有阅读完整的图像。在这种情况下,getMetadata() 只会读取图像像素之前的元数据 (它不会读取完整的图像,因为 PNGJ 的理念不是读取内存中的图像,而是让用户逐步进行)。如果您只想读取元数据并丢弃图像像素,那么您可以遍历所有图像行,或者更好的是,调用readSkippingAllRows() 并结束图像的读取。

    您还可以在写入时强制将文本块的位置放在像素数据之前,请参阅here

    【讨论】:

    • 哥们,你太棒了。
    • @AdroidFreak 你能成功创建PNG吗?尝试 leonbloy 建议的步骤时出现此异常: java.lang.NullPointerException: Null reference used for synchronization (monitor-enter) at java.util.zip.Deflater.end(Deflater.java:541)
    猜你喜欢
    • 2015-11-24
    • 2011-01-06
    • 1970-01-01
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多