C++ 使用Qt/QML从图像中获取特定像素及其坐标
我们正在创建一个有地图的游戏。在这些地图上,玩家可以行走,但要知道他们是否可以行走,我们有另一张图片,路径是绘制的 玩家可以通过点击地图来移动,如果点击与碰撞器图像匹配,角色应该使用探路器到达点击点。如果不是,则角色不移动 例如,以下是贴图及其碰撞路径图像: 我怎么知道我是否在Qt中单击了collider(这是一个只有一种颜色和透明度的png)? 我使用QML和FelGo进行渲染,所以如果已经有一种方法可以用QML来做,它甚至更好,但是我也可以在C++中实现。 我的第二个问题是如何做探路者?我知道算法,但我应该用像素移动吗 我已经看到了C++ 使用Qt/QML从图像中获取特定像素及其坐标,c++,image,qt,qml,collision,C++,Image,Qt,Qml,Collision,我们正在创建一个有地图的游戏。在这些地图上,玩家可以行走,但要知道他们是否可以行走,我们有另一张图片,路径是绘制的 玩家可以通过点击地图来移动,如果点击与碰撞器图像匹配,角色应该使用探路器到达点击点。如果不是,则角色不移动 例如,以下是贴图及其碰撞路径图像: 我怎么知道我是否在Qt中单击了collider(这是一个只有一种颜色和透明度的png)? 我使用QML和FelGo进行渲染,所以如果已经有一种方法可以用QML来做,它甚至更好,但是我也可以在C++中实现。 我的第二个问题是如何做探路者?
QPainterPath
类,这可能是我正在寻找的,我如何读取图像中具有特定颜色的所有像素并知道它们的坐标
谢谢- QML接口不能提供有效的方法来解决您的任务。应该在C++侧进行。
- 要获取图像数据,您可以使用:
- QImage加载图像
- 调用N次,每次读取K个像素。N等于以像素为单位的图像高度,K等于宽度
QImage::constScanLine
返回的uchar*
您应该调用QImage::format()
来确定uchar*
隐藏的像素格式。或者您可以调用QImage::convertToFormat(QImage::Format\u RGB32)
并始终将像素数据从uchar*
强制转换到自定义结构,如PixelData
:
#pragma pack(push, 1)
struct PixelData {
uint8_t padding;
uint8_t r;
uint8_t g;
uint8_t b;
};
#pragma pack(pop)
根据本文件:
以下是可编译的解决方案,用于将图像加载到RAM中,以便进一步有效地处理其数据:
#include <QImage>
#pragma pack(push, 1)
struct PixelData {
uint8_t padding;
uint8_t r;
uint8_t g;
uint8_t b;
};
#pragma pack(pop)
void loadImage(const char* path, int& w, int& h, PixelData** data) {
Q_ASSERT(data);
QImage initialImage;
initialImage.load(path);
auto image = initialImage.convertToFormat(QImage::Format_RGB32);
w = image.width();
h = image.height();
*data = new PixelData[w * h];
PixelData* outData = *data;
for (int y = 0; y < h; y++) {
auto scanLine = image.constScanLine(y);
memcpy(outData, scanLine, sizeof(PixelData) * w);
outData += w;
}
}
void pathfinder(const PixelData* data, int w, int h) {
// Your algorithm here
}
void cleanupData(PixelData* data) {
delete[] data;
}
int main(int argc, char *argv[])
{
int width, height;
PixelData* data;
loadImage("D:\\image.png", width, height, &data);
pathfinder(data, width, height);
cleanupData(data);
return 0;
}
。。。或者在您的寻路算法中的某个地方使用此公式,这样会更有效。- QML接口不能提供有效的方法来解决您的任务。应该在C++侧进行。
- 要获取图像数据,您可以使用:
- QImage加载图像
- 调用N次,每次读取K个像素。N等于以像素为单位的图像高度,K等于宽度
QImage::constScanLine
返回的uchar*
您应该调用QImage::format()
来确定uchar*
隐藏的像素格式。或者您可以调用QImage::convertToFormat(QImage::Format\u RGB32)
并始终将像素数据从uchar*
强制转换到自定义结构,如PixelData
:
#pragma pack(push, 1)
struct PixelData {
uint8_t padding;
uint8_t r;
uint8_t g;
uint8_t b;
};
#pragma pack(pop)
根据本文件:
以下是可编译的解决方案,用于将图像加载到RAM中,以便进一步有效地处理其数据:
#include <QImage>
#pragma pack(push, 1)
struct PixelData {
uint8_t padding;
uint8_t r;
uint8_t g;
uint8_t b;
};
#pragma pack(pop)
void loadImage(const char* path, int& w, int& h, PixelData** data) {
Q_ASSERT(data);
QImage initialImage;
initialImage.load(path);
auto image = initialImage.convertToFormat(QImage::Format_RGB32);
w = image.width();
h = image.height();
*data = new PixelData[w * h];
PixelData* outData = *data;
for (int y = 0; y < h; y++) {
auto scanLine = image.constScanLine(y);
memcpy(outData, scanLine, sizeof(PixelData) * w);
outData += w;
}
}
void pathfinder(const PixelData* data, int w, int h) {
// Your algorithm here
}
void cleanupData(PixelData* data) {
delete[] data;
}
int main(int argc, char *argv[])
{
int width, height;
PixelData* data;
loadImage("D:\\image.png", width, height, &data);
pathfinder(data, width, height);
cleanupData(data);
return 0;
}
。。。或者在寻路算法中的某个地方使用此公式,这样会更有效。您可以使用从当前位置到目标位置的一条线,并检查遮罩中该线上的所有像素(第二幅图像)。计算直线上的像素(坐标),我想到了。(而且,我一直认为这些知识现在已经过时了……;-)对不起,我忘了告诉你玩家应该如何移动(我已经编辑了我的帖子)。你的算法的问题是,我的播放器只能在一条线上移动,它不允许以路径移动。最后,我的问题是如何读取图像的像素并将其转换为Qt的coordonate。我不想要路径算法,我知道其中的一些算法(但我很乐意接受这些技巧),那么呢?@folibis在阅读文档后,似乎不建议使用QImage::pixel()进行大规模操作。但是我想为我的探路者创建一个像素地图。所以我需要检查所有像素!如果我只是在一开始就这么做,这是否被视为“大规模操纵”?文档建议使用QImage::constBits(),但它返回第一个像素的uchar,我不知道如何使用它检查所有像素的颜色值……您可以使用从当前位置到目标位置的一条线,并检查遮罩中该线上的所有像素(第二张图像)。计算直线上的像素(坐标),我想到了。(而且,我一直认为这些知识现在已经过时了……;-)对不起,我忘了告诉你玩家应该如何移动(我已经编辑了我的帖子)。你的算法的问题是,我的播放器只能在一条线上移动,它不允许以路径移动。最后,我的问题是如何读取图像的像素并将其转换为Qt的coordonate。我不想要路径算法,我知道其中的一些算法(但我很乐意接受这些技巧),那么呢?@folibis在阅读文档后,似乎不建议使用QImage::pixel()进行大规模操作。但是我想为我的探路者创建一个像素地图。所以我需要检查所有像素!如果我只是在一开始就这么做,这是否被视为“大规模操纵”?文档建议使用QImage::constBits(),但它返回第一个像素的uchar,我不知道如何使用它检查所有像素的颜色值。。。