2017-12-18 267 views
0

我試圖將像素逐像素旋轉90度,似乎有一個數學問題,我無法弄清楚......和數組越界異常 here是我嘗試順時針旋轉90度的圖像

const unsigned char *srcData = source.getData(); 
unsigned char *dstData = new unsigned char[width * height * bpp]; 


size_t srcPitch = source.getRowSpan(); 
    size_t dstPitch = width * bpp; 

    for(int i=0; i<height; i++) 
    { 
     for(int j=0; j<width * bpp; j++) 
     { 
      rotatedData[(i * dstPitch) + j]= dstData[(height-i) * dstPitch + j]; 
     } 
    } 
+2

'*'具有(在數學和C++相同)比'-'優先級數字 – user463035818

+0

仍具有一定界限dstData [I + J *寬度* BPP] = srcData [(寬×BPP)* J + 1 - j]; –

+0

你已經有了dstPitch,不知道你爲什麼沒有在你的條件中使用它作爲inner for循環。 – Eddge

回答

1

首先,讓我們構建一個圖像描述符來跟蹤尺寸。

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]; 
    } 
    } 
} 
+0

非常感謝您的回答。但我仍然得到掃描圖像 –

+0

@ahmed安德烈:我不知道你是什麼意思的「掃描圖像」。 –

0

試試這個:

for (int j = 0; j<width * bpp; j++) 
    { 
     for (int i = 0 ; i<height; i++) 
     { 
      rotatedData[(height)*(dstPitch - j - 1) + i] = dstData[(i * dstPitch) + j]; 
     } 
    } 

,如果dstData沒有平方:

//define rotatedData_height before. 
    rotatedData[(rotatedData_height)*(dstPitch - j - 1) + i] = dstData[(i * dstPitch) + j]; 
+0

我試過了,但我得到scanlines ..似乎它不能正常工作 –

+0

你可以顯示你如何迭代for循環? –

+0

@ahmedandre添加了for循環。 – ariaman5