首先,讓我們構建一個圖像描述符來跟蹤尺寸。
struct ImageDescriptor {
std::size_t width;
std::size_t height;
std::size_t channels;
std::size_t stride() const { return width * channels; }
std::size_t offset(std::size_t row, std::size_t col, std::size_t chan) {
assert(0 <= row && row < height);
assert(0 <= col && col < width);
assert(0 <= chan && chan < channels);
return row*stride() + col*channels + chan;
// or, depending on your coordinate system ...
// return (height - row - 1)*stride() + col*channels + chan;
}
std::size_t size() const { return height * stride(); }
};
現在我們需要兩個ImageDescriptors來跟蹤我們兩幅圖像的尺寸。請注意,除非原始圖像是正方形,否則旋轉後的圖像將具有不同的寬度和高度(從而步幅)。具體來說,旋轉圖像的寬度將是源圖像的高度(反之亦然)。
const ImageDescriptor source(width, height, bpp);
ImageDescriptor target(height, width, bpp); // note width/height swap
執行轉換的常用方法是循環搜索目標像素並查找源像素。
unsigned char *rotated = new[target.size()];
for (std::size_t row = 0; row < target.height; ++row) {
for (std::size_t col = 0; col < target.width; ++col) {
for (std::size_t chan = 0; chan < target.channels; ++chan) {
rotated[target.offset(row, col, chan)] =
original[source.offset(col, row, chan)];
}
}
}
一旦你做對了,你可以努力消除不必要的計算。第一個機會就是通過目標圖像,因爲所有內容都是按照內存順序。第二個機會是,將通道迴路中的源偏移計算提升出來。最後,如果bpp是常量,則可以展開最內層的循環。
unsigned char *p = rotated;
for (std::size_t row = 0; row < target.height; ++row) {
for (std::size_t col = 0; col < target.width; ++col) {
const std::size_t base = source.offset(col, row, 0);
for (std::size_t chan = 0; chan < target.channels; ++chan) {
*p++ = original[base + chan];
}
}
}
'*'具有(在數學和C++相同)比'-'優先級數字 – user463035818
仍具有一定界限dstData [I + J *寬度* BPP] = srcData [(寬×BPP)* J + 1 - j]; –
你已經有了dstPitch,不知道你爲什麼沒有在你的條件中使用它作爲inner for循環。 – Eddge