まず、次元を追跡するための画像記述子を構築しましょう。
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(); }
};
ここでは、2つの画像の寸法を記録するために2つのImageDescriptorが必要です。元の画像が四角形でない限り、回転された画像の幅と高さが異なるため、ストライドになります。具体的には、回転イメージの幅はソースイメージの高さになります(またその逆もあります)。
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)];
}
}
}
正しくなったら、不要な計算を排除することができます。最初の機会は、すべてのものがメモリの順序であるので、宛先イメージを辿るだけです。第2の機会は、ソース・オフセット計算をチャネル・ループから引き上げることである。最後に、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];
}
}
}
は、 '*' – user463035818
まだdstDataは= srcData [(幅* BPP)* J + 1 [iがj個の*幅* BPPを+]いくつかの限界を有している(数学及びC++で同じ)より高い-' 'よりも優先を有します - j]; –
dstPitchを既に持っていますが、内側ループのためにあなたの条件でそれを使用していない理由はわかりません。 – Eddge