Android 系统(255)---dump解码所得图片方法

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出来

猜你喜欢

转载自blog.csdn.net/zhangbijun1230/article/details/81414385