Android 带有位图和自定义的 pngj header
Android pngj with Bitmap and custom header
我正在尝试使用 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
您必须自己进行转换。
最简单(如果不是最有效)的方法是:
- 实例化一个ImageLineInt(或ImageLineByte)
- 遍历 Bitmap 的每一行,调用
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。
我正在尝试使用 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
您必须自己进行转换。 最简单(如果不是最有效)的方法是:
- 实例化一个ImageLineInt(或ImageLineByte)
- 遍历 Bitmap 的每一行,调用
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。