lldb安装以及调试Android程序
  A0c7EqEBTaMm 2023年11月02日 44 0


Android Studio自带lldb,安装过程不再赘述。lldb官网https://lldb.llvm.org/use/map.html

需求

需要获取图片中每一个像素的RGBA值。

代码

Java端代码:

findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
            stringFromJNI(convertImageToBitmap(path));
    }
});

public Bitmap convertImageToBitmap(String imagePath) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    }
    Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
    return bitmap;
}

native测的代码, 从c++层拿到Java层传递过来的Bitmap。

Java_com_example_myapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */, jobject bmpObj) {
    AndroidBitmapInfo info;
    int ret;
    if ((ret = AndroidBitmap_getInfo(env, bmpObj, &info)) < 0)
    {
        return NULL;
    }
    if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888)
    {
        return NULL;
    }
    unsigned char* bitmapPixels;
    unsigned char* newBitmapPixels;
    //对bitmapPixels的所有操作可直接作用在BitMap上面
    if ((ret = AndroidBitmap_lockPixels(env, bmpObj, (void**)&bitmapPixels)) < 0)
    {
        return NULL;
    }
    getRGBA(bitmapPixels, info.width, info.height);
    AndroidBitmap_unlockPixels(env, bmpObj);
    std::string hello = "Hello from C++";

    return env->NewStringUTF(hello.c_str());
}

bitmapPixels数组的长度是所有像素点个数 * 4。为什么是乘以4,是因为rgba是四个值,这个数组从0开始每隔4个就是一个像素点的r/g/b/a值。所以数组的第0,1,2,3个值分别代表第一个像素点的r,g,b,a的值。从左到右,从上到下。

int getRGBA(unsigned char* ucImageData, int nWidth, int nHeight){
    if (ucImageData == NULL || file == NULL) {
        return 1;
    }
    int nChannel = 4;
    int nStep = nWidth * nChannel;

    for (int y = 0; y < nHeight; y++){
        for (int x = 0; x < nWidth; x++)
        {
            float r = (ucImageData[y * nStep + x * nChannel + 0]);
            float g = (ucImageData[y * nStep + x * nChannel + 1]);
            float b = (ucImageData[y * nStep + x * nChannel + 2]);
            float a = (ucImageData[y * nStep + x * nChannel + 3]);
        }
    }
    return 0;
}

另一种常见的写法:

int getRGBA(unsigned char* ucImageData, int nWidth, int nHeight){
    if (ucImageData == NULL || file == NULL) {
        return 1;
    }
    int nChannel = 4;
    int nStep = nWidth * nChannel;

    for (int y = 0; y < nHeight; y++){
        for (int x = 0; x < nWidth; x++)
        {
            float r = (ucImageData[(y * width + x) * 4 + 0]);
            float g = (ucImageData[(y * width + x) * 4 + 1]);
            float b = (ucImageData[(y * width + x) * 4 + 2]);
            float a = (ucImageData[(y * width + x) * 4 + 3]);
        }
    }
    return 0;
}

lldb命令

查看Disassemble
(lldb) disassemble --name main
(lldb) di -n main

lldb安装以及调试Android程序_像素点

查看寄存器
register read rax rsp rbp

lldb安装以及调试Android程序_像素点_02

查看局部变量
(lldb) frame variable
(lldb) fr v

lldb安装以及调试Android程序_像素点_03

查看调用堆栈
(lldb) thread backtrace all
(lldb) bt all

lldb安装以及调试Android程序_android_04

查看内存
(lldb) memory read --size 4 --format x --count 4 0xbffff3c0
(lldb) me r -s4 -fx -c4 0xbffff3c0
(lldb) x -s4 -fx -c4 0xbffff3c0

lldb安装以及调试Android程序_ide_05


lldb安装以及调试Android程序_像素点_06


还有许多其他操作,比如修改值,单步调试等,这个都可以通过Android Studio进行手动操作,不再赘述。

Android Studio的 Evaluate Expression功能

lldb安装以及调试Android程序_Java_07

参考

canvas - 使用getImageData()方法获取canvas的每一个像素点的rgba值。以及如何提取该像素点的rgba值。

GDB to LLDB command map

公众号

更多内容,欢迎关注我的微信公众号:半夏之夜的无情剑客。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
A0c7EqEBTaMm