使用像素阵列在 SFML 中操作图像
嘿,所以我正在尝试创建一个接受图像引用和 sf::IntRect 的函数
(这有 4 个整数,代表矩形的顶部、底部、左侧和右侧。这个矩形代表正在显示的图像,但实际上并没有切除矩形之外的像素)
,然后通过切除 IntRect 之外的像素来创建一个新的压缩图像。我想我能做到这一点的唯一方法是制作一个与 IntRect 尺寸相同的二维像素数组,然后通过迭代图像来填充它,但由于我不知道 IntRect 的尺寸,所以我无法制作一个常量数组......
这个问题不断出现,我假设做一堆向量工作和转换到 c_style 数组会消耗大量性能..
是否有一些简单的解决方案来大量操作/更改维度和颜色图像?
Hey so i'm trying to make a function that takes in an image refrence and sf::IntRect
(this has 4 ints representing the top,bottom,left, and right sides of a rectangle. this rectangle represents the part of the image being displayed, but does not actually cut off the pixels outside the rectangle)
and then creates a new condensed image by cutting off the pixels outside the IntRect. I figured the only way i could do this was by making a 2d pixel array of the same dimensions as the IntRect, and then filling it by iterating through the image, but since i do not know the IntRect's dimensions i can't make a constant array......
This problem continually comes up, i assume doing a bunch of vector work and convesions to c_style arrays would cost a lot of performance..
Is there some simple sollution to heavily manipulating/ changing the dimensions and colors of images?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
存储和访问二维图像(或任何具有可变大小的二维矩阵)的常用方法是分配合适大小的一维数组(
宽度*高度
,或(width + padding) * height
),并“手动”计算数组的索引 (y * stride + x
,其中stride
是宽度+内边距
)。(我通常使用 std::vector 来表示一维数组,但这是一个不同的故事)
引用 2D 图像数据的常用方法(按引用传递中的引用)是传递元组:
void* imageData
-- 左上角像素的地址size_t stride
-- 添加到imageData
的字节数到达下一行size_t width
size_t height
SomeEnum PixelFormat
--图像的像素格式(如果只有一个可以省略)当然如果有的话仅是一种像素格式,您可以使用类型指针,并以该类型(而不是字节)为单位指定
stride
。使用这样的引用,您可以非常轻松且高效地访问循环中的像素:以
这种方式传递图像引用的好处是,您始终可以“调整”这样的引用以指向原始图像的子矩形。您只需相应地调整值:使
imageData
指向子矩形的左上角像素,并将width
和height
设置为子矩形的宽度和高度。stride
保持不变。这意味着您不必“具体化”裁剪后的图像,您只需将对子矩形的引用传递给任何函数,它将对该子矩形进行操作,就像在“完整”图像上一样。
如果您确实想“具体化”裁剪后的图像,那么您现在也应该有足够的信息来做到这一点。至少我希望如此:)
编辑:由于您对 sf::IntRect 部分非常明确,但随后只写了“image”而不是 sf::Image,我认为您在谈论某些内容您管理自己,而不是 sf::Image。好吧...
如果您只想将 sf::Image 的子矩形复制到另一个 sf::Image,您可以这样做:
The usual way to store and access 2-dimensional images (or any 2-dimensional matrix with variable size), is to allocate a 1-dimensional array of suitable size (
width * height
, or(width + padding) * height
), and calculate the index into the array "manually" (y * stride + x
, wherestride
iswidth + padding
).(I normally use
std::vector
for that 1-dimensional array, but that's a different story)The usual way to reference 2D image data (reference as in pass-by-reference), is to pass a tuple of:
void* imageData
-- the address of the top-left pixelsize_t stride
-- the number of bytes to add toimageData
to get to the next linesize_t width
size_t height
SomeEnum pixelFormat
-- the pixel format of the image (can be omitted if there is only one)Of course, if there is only one Pixel-Format, you can use a typed pointer, and specify the
stride
in units of that type (instead of bytes).Using such a reference, you can access pixels in a loop quite easily and quite efficient:
The nice thing about passing image references that way is, that you can always "adjust" such a reference to point to a sub-rect of the original image. You just have to adjust the values accordingly: make
imageData
point to the top-left pixel of the sub-rect and setwidth
andheight
to the width and height of the sub-rect.stride
stays the same.That means you don't have to "materialize" the cropped image, you can just pass a reference to a sub-rect to any function, and it will operate on that sub-rect just as it would on a "complete" image.
And if you really want to "materialize" a cropped image, you should now have enough information to do that too. At least I hope so :)
EDIT: Since you were very explicit about the sf::IntRect part, but then only wrote "image" instead of sf::Image, I assumed you were talking about something you manage yourself, not an sf::Image. Well...
If you just want to copy a sub-rect of an sf::Image to another sf::Image, you can just do this: