dump解码所得图片方法
主要是为了查看skia解码所得的图片是否异常
1. 若是3rd party apk图片有问题,不知道图片是什么格式的,不知道调用的图片解码的接口是哪个,可以在framwork添加dump信息。
修改文件BitmapFactory.java, 复现问题,抓取mtklog并提供手机DCIM目录下生成的png图片。
1>. 添加如下方法:
private static void dumpBitmap(Bitmap b, String name) { if (name == null) { name = "Bitmap"; } if (b != null) { try{ }catch(Exception e){ e.printStackTrace(); } java.io.FileOutputStream fos = null; try { String time= new java.text.SimpleDateFormat("yyyyMMdd_HHmmss_SSS") .format(new java.util.Date()); String filename = android.os.Environment.getExternalStorageDirectory().toString()+"/DCIM/" + name + "["+ time + "].png"; fos = new java.io.FileOutputStream(filename); b.compress(Bitmap.CompressFormat.PNG, 100, fos); } catch (java.io.IOException ex) { } finally { if (fos != null) { try { fos.close(); } catch (java.io.IOException ex) { } } } } }
2>. 添加add by mtk 部分
public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) { Log.d("mtk debug", "decodeByteArray() start");//add by mtk ........... Log.d("mtk debug", "decodeByteArray() end");//add by mtk //add by mtk to dump Bitmap if(bm.getWidth() > 400 && bm.getHeight() > 400) // 图片的宽高视情况可以适当调整 dumpBitmap(bm,"ByteArray"); //add by mtk to dump Bitmap end return bm; }
3>. 添加add by mtk 部分
public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) { // we don't throw in this case, thus allowing the caller to only check // the cache, and not force the image to be decoded. Log.d("mtk debug", "decodeStream() start");//add by mtk ............ Log.d("mtk debug", "decodeStream() end");//add by mtk //add by mtk to dump Bitmap if(bm.getWidth() > 400 && bm.getHeight() > 400) // 图片的宽高视情况可以适当调整 dumpBitmap(bm,"Stream"); //add by mtk to dump Bitmap end return bm; }
4>. 添加add by mtk 部分
public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) { Log.d("mtk debug", "decodeFileDescriptor() start");//add by mtk ............ Log.d("mtk debug", "decodeFileDescriptor() end");//add by mtk //add by mtk to dump Bitmap if(bm.getWidth() > 400 && bm.getHeight() > 400) // 图片的宽高视情况可以适当调整 dumpBitmap(bm,"FD"); //add by mtk to dump Bitmap end return bm; }
2. 如果确切知道是什么格式的图片解码,或者希望dump SkBitmap(比如:拍照或者其他方式对应的JPEG图片对应的文件是/external/skia/src/mtk/SkImageDecoder_libjpeg.cpp),
1>. 添加文件:
#include "SkImageEncoder.h"
#include "SkTime.h"
#include "SkString.h"
#include <unistd.h>
下面的步骤Android N之前跟Android O有差异,这里是Android N的做法:
2>. 增加新方法:
// 宽、高大于300才dump, 可以视图片的尺寸不同适当修改 static void saveToFile(const char name[], const SkBitmap& bm) { if (bm.width() > 300 && bm.height() > 300) { SkImageEncoder::EncodeFile(name, bm, SkImageEncoder::kPNG_Type, 100); } }
3>. 在需要dump SkBitmap的位置增加:
SkMSec now = SkTime::GetMSecs(); SkDebugf("dump SkBitmap, start>>>%u", now); if (access("/sdcard/images", F_OK) == 0) { SkString filename; filename.printf("/sdcard/images/%u.png", now); SkDebugf("SkBitmap save to file %s", filename.c_str() ); saveToFile(filename.c_str(), *bm); }
下面是Android O的修改:
2>. 增加新方法:
static void saveToFile(const char name[], const SkBitmap& bm) { SkString filename; SkMSec now = SkTime::GetMSecs(); SkDebugf("dump SkBitmap, start>>>%u", now); filename.printf("/sdcard/images/%s_%u.jpg", name, now); SkDebugf("SkBitmap save to file %s", filename.c_str() ); int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0664); if ( fd > 0) { struct FDWStream final : public SkWStream { size_t fBytesWritten = 0; int fFd; FDWStream(int f) : fFd(f) {} size_t bytesWritten() const override { return fBytesWritten; } bool write(const void* buffer, size_t size) override { fBytesWritten += size; return size == 0 || ::write(fFd, buffer, size) > 0; } } fdStream(fd); SkEncodeImage((SkWStream *)&fdStream, bm, SkEncodedImageFormat::kPNG, 100); } }
3>. 在需要直接dump 添加saveToFile语句做dump即可,比如需要dump MDP前后bitmap的数据,直接按下列方式使用这个接口即可
{saveToFile("linexxx", bitmap);//xxx表示当前line的数值 #ifdef MTK_SKIA_USE_ION //result = MDPResizer(hwBuffer, fIonClientHnd, srcAllocator.getFD(), width, height, sc, &bitmap, colorType, enTdshp, pParam, fISOSpeedRatings); result = MDPResizer(hwBuffer, fIonClientHnd, srcAllocator.getFD(), width, height, sc, &bitmap, colorType, enTdshp, nullptr, fISOSpeedRatings); #else //result = MDPResizer(hwBuffer, 0, -1, width, height, sc, &bitmap, colorType, enTdshp, pParam, fISOSpeedRatings); result = MDPResizer(hwBuffer, 0, -1, width, height, sc, &bitmap, colorType, enTdshp, nullptr, fISOSpeedRatings); #endif saveToFile("linexxx", bitmap);//xxx表示当前line的数值
:
除代码修改外,还要进行以下操作:
(1)手机连上USB,执行如下命令
adb shell
cd sdcard
mkdir images
chmod 777 images
(2)然后复现问题,将/sdcard/images/目录下面的png图片都pull出来