前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >1. 解析Bitmap的ARGB,实现图片颜色选择器

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

作者头像
公号sumsmile
发布2020-10-28 14:08:44
1.8K0
发布2020-10-28 14:08:44
举报
  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; 详细代码如下:

代码语言:javascript
复制
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中

代码语言:javascript
复制
                    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;最后发送信号

代码语言:javascript
复制
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中数据的长度有限

代码语言:javascript
复制
        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;
            }
        }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • bitmap 中每个像素的ARGB内存分布
  • 读取每一个像素值
  • 实现颜色选择
    • 1. 获取鼠标点击坐标对应的图片像素坐标,传递给C++,这里简单处理,图片平铺到Image中
      • 2.C++中解析Bitmap,注意url是file:///协议,qml中可以识别,C++中不能直接识别,需要处理下;Qt中C++与qml传参有限制,这里需要传递数组,用QVariantList->转场QVariant;最后发送信号
        • qml中接收信号,展示结果。注意js中数据的长度有限
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档