我想编写一个在BGR中转换BGRA的函数。
void convertBGRAViewtoBGRView( const boost::gil::bgra8_view_t &src, boost::gil::bgr8_view_t dst )
如果我这样写:
size_t numPixels = src.width() * src.height();
boost::gil::bgra8_view_t::iterator it = src.begin();
boost::gil::bgr8_view_t::iterator itD = dst.begin();
for( int i = 0; i < numPixels; ++i ){
boost::gil::bgra8_pixel_t pixe(it[0]);
*it++;
boost::gil::bgr8_pixel_t pix(pixe[0],pixe[1],pixe[2]);
*itD++ = pix;
}
它有效,但速度很慢。所以我想使用NEON指令,因此我需要一个指针(例如UInt8 *)或(UInt32 *)。 我试过这样的话:
UInt32 *temp = (UInt32*)&src(0,0);
for( int i = 0; i < numPixels; ++i ){
boost::gil::bgr8_pixel_t pixk( (( *temp) & 0xff), ( (*temp>>8) & 0xff), ((*temp >> 16 )& 0xff));
*itD++ = pixk;
temp += 1;
}
这或多或少有效,但生成的图像不正确。我认为可能是对齐问题。有谁知道如何让它工作? 该解决方案比使用迭代器的解决方案快约3倍。
更新: 我检查了调试器: src的宽度为480x360,直到i == 259,一切都是正确的,但是后面的迭代器和指针的解决方案是不同的。
感谢。
答案 0 :(得分:2)
在根据你的答案进行一些计算之后,我发现360*4
可以被任何高达32的东西分割,而360*4+8*4
甚至可以被64分割。所以我猜错误的原因是在您的情况下,GIL尝试将图像行对齐为64字节边界,因此不会连续存储它们。
因此,总是建议使用通用迭代器接口而不是直接弄乱原始内存,否则你必须完全确定任何这样的对齐约定(但也许它们是完全标准化的,可以在某处读取文件)。
答案 1 :(得分:0)
好的我找到了如何解决它,但仍然不知道原因:) 这适用于我的情况下宽度为360的图像。
UInt32 *temp = (UInt32*)&src(0,0);
for( int i = 0; i < numPixels; ++i ){
if( i%360==0 && i!=0 ){
temp += 8;
}
boost::gil::bgr8_pixel_t pixk( (( *temp) & 0xff), ( (*temp>>8) & 0xff), ((*temp >> 16 )& 0xff));
*itD++ = pixk;
temp += 1;
}
在iOS平台上使用这个更好:
UInt8 *temp = (UInt8*)&src(0,0);
for( int i = 0; i < numPixels; ++i ){
if( i%360==0 && i!=0 ){
temp += 8*4;
}
boost::gil::bgr8_pixel_t pixk( *temp, *(temp+1), *(temp+2));
*itD++ = pixk;
temp += 4;
}
摆脱其他迭代器可以进一步提高速度(在iOS上测试)。