专栏首页音视频技术学习笔记1. 解析Bitmap的ARGB,实现图片颜色选择器

1. 解析Bitmap的ARGB,实现图片颜色选择器

  1. UI界面读取一张图片,鼠标选中一个position,计算出对应图片的像素坐标,传给c++
  2. c++中读取图片地址,解析出*char数组,根据ARGB协议,解析出ARGB的值,传递给UI界面
  3. 在UI界面中解析ARGB值,显示对应的颜色和16进制的字符串表示

bitmap 中每个像素的ARGB内存分布

因为大小端的缘故,和我们理解的ARGB的顺序相反,大小端读者有兴趣可以深入了解,

参考:https://zhuanlan.zhihu.com/p/25119530

读取每一个像素值

像素是以char* 格式存储在内存中,是一个一位数组,bitmap中记录了每一行的长度,即步辐,每个平台都有API可以获取 一个像素对应的bitmap内存位置为: b = y * stride + x * 4 // 计算的是b通道 g = b + 1; r = b + 2; a = b + 3; 详细代码如下:

int f_getPixel(unsigned char *srcData, int width, int height, int stride, int x, int y, int argb[4])
{
    x = x < 0 ? 0 : (x > width - 1 ? width - 1 : x);
    y = y < 0 ? 0 : (y > height - 1 ? height - 1 : y);
    int ret = 0;
    if(srcData == nullptr)
    {
        printf("input image is null!");
        return -1;
    }
    //Process
    int pos = x * 4 + y * stride;
    argb[0] = srcData[pos + 3];
    argb[1] = srcData[pos + 2];
    argb[2] = srcData[pos + 1];
    argb[3] = srcData[pos + 0];
    return ret;
}

实现颜色选择

这里基于qml来处理,读者有兴趣迁移到Android/iOS也不复杂

1. 获取鼠标点击坐标对应的图片像素坐标,传递给C++,这里简单处理,图片平铺到Image中

                    var pox = (mouseX / 640) *imageViewer.sourceSize.width;
                    var poy = (mouseY / 480) * imageViewer.sourceSize.height;
                    console.log("pox = ", pox, "poy = ", poy);
                    processor.getPix(fileDialog.fileUrl, pox, poy);

2.C++中解析Bitmap,注意url是file:///协议,qml中可以识别,C++中不能直接识别,需要处理下;Qt中C++与qml传参有限制,这里需要传递数组,用QVariantList->转场QVariant;最后发送信号

void ImageProcessor::getPix(QString sourceFile, int x, int y)
{
    const QUrl url(sourceFile);
    if (url.isLocalFile()) {
        sourceFile = QDir::toNativeSeparators(url.toLocalFile());
    }
    QImage image(sourceFile);
    if(image.isNull())
    {
        return;
    }
    unsigned char *data = image.bits();
    int w = image.width();
    int h = image.height();
    int stride = image.bytesPerLine();
    int argb[4];
    f_getPixel(data, w, h, stride, x, y, argb);
    QVariantList list;
    list<<argb[0]<<argb[1]<<argb[2]<<argb[3];

    emit getPixDone(QVariant::fromValue(list));
}

qml中接收信号,展示结果。注意js中数据的长度有限

        ImageProcessor {

            function rgba(a,r,g,b){
                var ret = (r << 16 | g << 8 | b);
                var strRet =  ("#" + a.toString(16) + ret.toString(16)).toUpperCase();
                return strRet;
            }
            id: processor;
            onFinished: {
                imageViewer.source = "file:///" +newFile;
            }
            onGetPixDone: {
                var selectColor = rgba(list[0], list[1],list[2],list[3]);
                position.color = selectColor;
                positionTex.text = selectColor;
            }
        }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 照片处理-几何滤镜实现哈哈镜

    几何滤镜比较简单,不涉及色彩模型,按照某种算法,对原图进行采样,得到一张新的图片。看起来就像是把原图进行了几何变形。 这篇文章通过两个简单的案例,更直观的感受...

    用户1068165
  • 39.opengl-游戏实战

    用户1068165
  • 音视频技术(4)-SDL播放PCM

    用户1068165
  • 《权力的游戏》最终季上线!谁是你最喜爱的演员?这里有一份Python教程 | 附源码

    《权力的游戏》最终季已于近日开播,对于全世界翘首以待的粉丝们来说,其最大的魅力就在于“无法预知的人物命运”。那些在魔幻时代的洪流中不断沉浮的人们,将会迎来怎样的...

    AI科技大本营
  • 2018 Wannafly summer camp Day3--Knight

    Knight 题目描述: 有一张无限大的棋盘,你要将马从(0,0)(0,0)(0,0)移到(n,m)(n,m)(n,m)。 每一步中,如果马在(x,...

    Enterprise_
  • Android 使用Canvas在图片上绘制文字的方法

    在Android SDK中使用Typeface类来定义字体,可以通过常用字体类型名称进行设置,如设置默认黑体:

    砸漏
  • Leetcode: Valid Sudoku

    题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.

    卡尔曼和玻尔兹曼谁曼
  • 简单易学的机器学习算法——马尔可夫链蒙特卡罗方法MCMC

    对于一般的分布的采样,在很多的编程语言中都有实现,如最基本的满足均匀分布的随机数,但是对于复杂的分布,要想对其采样,却没有实现好的函数,在这里,可以使用马尔可夫...

    zhaozhiyong
  • 大地云网殷康:SD-WAN技术及市场趋势

    2018中国SD-WAN峰会已经圆满落幕,大地云大地云网殷康为我们带来主题演讲“SD-WAN技术及市场趋势”。

    SDNLAB
  • 公众号对接时出现“URL请求超时” token check timeout报错,已完美解决

    windows下,测试号/公众号接口配置信息报错 token check timeout,数据库配置时可将localhost改为127.0.0.1即可!

    断桥易哥

扫码关注云+社区

领取腾讯云代金券