android bitmap大小端,1. 解析Bitmap的ARGB,实现图片颜色选择器

这篇博客介绍了如何在UI界面中选取图像的一个位置,通过计算得到对应的像素坐标,并利用C++和Qt进行ARGB像素值的解析和传递。文章详细阐述了像素内存布局,特别是大小端问题,以及如何在C++中读取图片并获取像素值。最后,展示了在QML中如何接收和显示所选像素的颜色信息。
摘要由CSDN通过智能技术生成

aab3eef112af

UI界面读取一张图片,鼠标选中一个position,计算出对应图片的像素坐标,传给c++

c++中读取图片地址,解析出*char数组,根据ARGB协议,解析出ARGB的值,传递给UI界面

在UI界面中解析ARGB值,显示对应的颜色和16进制的字符串表示

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

aab3eef112af

因为大小端的缘故,和我们理解的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<

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;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值