c++ - 使用像素阵列在 SFML 中操作图像

标签 c++ image-manipulation pixel vector-graphics sfml

嘿,所以我正在尝试制作一个接受图像引用和 sf::IntRect 的函数

(这有4个整数分别代表一个矩形的上、下、左、右。这个矩形代表了图像中显示的部分,但实际上并没有切掉矩形外的像素)

然后通过切断 IntRect 之外的像素来创建一个新的压缩图像。我想我能做到这一点的唯一方法是制作一个与 IntRect 具有相同尺寸的二维像素数组,然后通过遍历图像来填充它,但是由于我不知道 IntRect 的尺寸,所以我无法制作一个常数数组……

这个问题不断出现,我假设做一堆 vector 工作和转换到 c_style 数组会消耗很多性能..

是否有一些简单的解决方案来大量操纵/更改图像的尺寸和颜色?

最佳答案

存储和访问二维图像(或任何具有可变大小的二维矩阵)的常用方法是分配一个大小合适的一维数组(width * height,或者(width + padding) * height),并“手动”计算数组中的索引(y * stride + x,其中 stride宽度 + 填充)。

(我通常对一维数组使用 std::vector,但这是另一回事)

引用 2D 图像数据的常用方法(引用传递引用)是传递一个元组:

  • void* imageData -- 左上像素的地址
  • size_t stride -- 添加到 imageData 以到达下一行的字节数
  • size_t 宽度
  • size_t 高度
  • SomeEnum pixelFormat -- 图片的像素格式(只有一个可以省略)

当然,如果只有一种 Pixel-Format,您可以使用类型指针,并以该类型(而不是字节)为单位指定 stride

使用这样的引用,您可以非常轻松高效地访问循环中的像素:

size_t const bytesPerPixel = GetBytesPerPixel(ref->pixelFormat);

for (size_t y = 0; y < ref->height; y++)
{
    unsigned char* currentLine =
        static_cast<unsigned char*>(ref->imageData) + ref->stride * y;

    for (size_t x = 0; x < ref->width; x++)
    {
        // any modern compiler will optimize the multiplication below to
        // an incremental addition
        unsigned char* currentPixel = currentLine + bytesPerPixel * y;

        // do something to the pixel data at
        // currentPixel[0] ... currentPixel[bytesPerPixel - 1]
    }
}

以这种方式传递图像引用的好处是,您始终可以“调整”这样的引用以指向原始图像的子矩形。您只需要相应地调整值:使 imageData 指向子矩形的左上角像素并将 widthheight 设置为子矩形的宽度和高度。 stride 保持不变。

这意味着您不必“具体化”裁剪后的图像,您只需将对子矩形的引用传递给任何函数,它将对该子矩形进行操作,就像在“完整”上一样"图片。

如果您真的想“具体化”裁剪后的图像,您现在也应该有足够的信息来做到这一点。至少我希望如此:)

编辑: 由于您对 sf::IntRect 部分非常明确,但后来只写了“image”而不是 sf::Image,我假设您在谈论您自己管理的事情,不是 sf::Image。嗯……

如果你只是想复制一个 sf::Image 的子矩形到另一个 sf::Image,你可以这样做:

sf::Image sourceImage = ...;
sf::IntRect subRect = ...;

// construct an empty sf::Image with the appropriate dimensions
sf::Image newImage(subRect.GetWidth(), subRect.GetHeight());

// copy the pixel data into the new image
newImage.Copy(sourceImage, 0, 0, subRect);

关于c++ - 使用像素阵列在 SFML 中操作图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6351466/

相关文章:

c++ - 我如何获得画笔的句柄,Win32 C++

c++ - 模板友元函数重载

python - Numpy 图像 - 将矩阵旋转 270 度

imagemagick - 是否可以使用 GD 或类似图像从图像中提取 "punch"纹理文本?

ios - 为什么当我减少图片中的像素数量时,文件的大小会变大?

html - 如何获取html5 Canvas 内像素的像素坐标

C++ header 包含

c++ - 具有权重系数的二维函数的逼近

c# - 4 点变换图像

css - 是否有各种设备的 'CSS pixel ratio' 值的数据库?