Android中FFmpeg添加PNG水印报错,求助解决方法
解决Android中FFmpeg加载PNG水印时的Invalid PNG Signature错误
兄弟,我一眼就揪出问题了——你用ObjectOutputStream来写入Bitmap的压缩数据,这完全是用错工具了!ObjectOutputStream是用来序列化Java对象的,它会在文件开头塞一堆额外的序列化签名(就是报错里的0xACED0005...),导致生成的根本不是标准PNG文件,FFmpeg当然认不出来。
修正后的代码
直接替换你的Bitmap保存逻辑,去掉多余的ObjectOutputStream,用FileOutputStream直接写入压缩数据:
Bitmap watermark = BitmapFactory.decodeResource(getResources(), R.drawable.watermark); FileOutputStream fos = model.controller.openFileOutput("watermark.png", Context.MODE_PRIVATE); // 直接用FileOutputStream写入PNG压缩数据,不要用ObjectOutputStream boolean success = watermark.compress(Bitmap.CompressFormat.PNG, 100, fos); fos.flush(); fos.close(); // 记得回收Bitmap,避免内存泄漏 watermark.recycle();
问题根源解释
- PNG文件有固定的开头签名:
89 50 4E 47 0D 0A 1A 0A(对应十六进制),FFmpeg会先检查这个签名来识别文件类型。 - 而
ObjectOutputStream写入的文件开头是Java序列化的魔数0xACED,后面跟着序列化版本号等信息,完全破坏了PNG的标准结构,所以FFmpeg抛出了Invalid PNG signature错误,后续的解码和滤镜配置自然也失败了。
额外检查点
- 确认
R.drawable.watermark本身是有效的PNG图片,避免源文件就存在格式问题。 - 保存后可以查看生成文件的大小,如果只有几十字节,那肯定是序列化头导致的,正常PNG水印至少有几百字节。
- 也可以读取文件前8个字节,验证是否符合PNG的标准签名。
内容的提问来源于stack exchange,提问作者Bob Lissner
相关产品推荐
相关产品推荐

