因为大小端的缘故,和我们理解的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也不复杂
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);
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)); }
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; } }
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句