c++ - 如何反转数组的一部分?
问题描述
我正在编写一个将位图文件读入内存的程序。但是当我将它读入内存时,我正在做一些改变。首先,我正在反转像素的颜色。我设法让这个工作。现在我试图在 Y 轴上翻转图像。我曾尝试使用两个 for 循环,但最终会出现分段错误,而且我也不喜欢它看起来有多乱。在我的第二次尝试中,我发现了一种更简洁的不同方法,因为它只使用一个循环和一个条件,而不是 2 个循环和 2 个条件。我的代码现在没有产生错误,但没有执行预期的操作。我可以尝试另一种算法吗?
下面是我的部分程序的一些代码。当我逐行读取它们时,我试图反转像素。
fseek(fin, bfh.offset, SEEK_SET);
Pixel *p = new Pixel[bih.height * bih.width];
for (uint32_t i = 0; i < bih.height; i++) {
for (uint32_t j = 0; j < bih.width; j++) {
uint32_t index = i * bih.width + j;
fread(&p[index], 1, sizeof(p[0]), fin);
p[index].blue = 255 - p[index].blue;
p[index].green = 255 - p[index].green;
p[index].red = 255 - p[index].red;
}
uint32_t k = (bih.width * i) - 1;
uint32_t c = 0 + (i * bih.width);
if ( i == 0) {
k = bih.width - 1;
}
while( c < k)
{
temp = p[c];
p[c] = p[k];
p[k] = temp;
c++;
k--;
}
fseek(fin, padding_bytes, SEEK_CUR);
}
fclose(fin);
如果需要,下面是我的整个程序。
#include <cstdint>
#include <cstdio>
#pragma pack(push, 2)
struct BitmapFileHeader {
uint16_t type;
uint32_t size;
uint16_t reserved_1;
uint16_t reserved_2;
uint32_t offset;
};
struct BitmapInfoHeader {
uint32_t size;
uint32_t width;
uint32_t height;
uint16_t planes;
uint16_t bitcount;
uint32_t compression;
uint32_t imagesize;
uint32_t x_pixels_per_meter;
uint32_t y_pixels_per_meter;
uint32_t color_used;
uint32_t color_important;
};
#pragma pack(pop)
struct Pixel {
uint8_t blue;
uint8_t green;
uint8_t red;
};
int main(int argc, char* argv[])
{
if(argc != 3) {
printf("Usage : %s input_file output_file\n", argv[0]);
return 1;
}
FILE *fin;
FILE *fout;
BitmapFileHeader bfh;
BitmapInfoHeader bih;
Pixel temp;
fin = fopen(argv[1], "rb");
if (nullptr == fin) {
perror(argv[1]);
return -1;
}
if (sizeof(BitmapFileHeader) != fread(
&bfh,
1,
sizeof(bfh),
fin
)) {
printf("Unable to read bitmap file header. \n");
return -2;
}
if (sizeof(BitmapInfoHeader) != fread(
&bih,
1,
sizeof(bih),
fin
)) {
printf("Unable to read bitmap info header. \n");
return -3;
}
printf("Size of File Header = %lu\n", sizeof(BitmapFileHeader));
int8_t first = (bfh.type >> 8) & 0xff;
int8_t second = bfh.type & 0xff;
if ( (first != 'M') && (second != 'B') ){
printf("Input file is not a Bitmap file. \n");
return -4;
}
printf("File type = %c%c\n", first, second);
printf("File size = %u\n", bfh.size);
printf("File offset = %u\n", bfh.offset);
printf("File width = %u\n", bih.width);
printf("Info size = %u\n", bih.size);
uint32_t padding_bytes = 0;
uint32_t row_bytes_final = bih.width * sizeof(Pixel);
uint32_t row_bytes_initial = row_bytes_final;
do{
uint32_t rem = row_bytes_final % 4;
if (rem != 0) {
row_bytes_final += 1;
}
padding_bytes = row_bytes_final - row_bytes_initial;
} while( (row_bytes_final % 4) != 0);
fseek(fin, bfh.offset, SEEK_SET);
Pixel *p = new Pixel[bih.height * bih.width];
for (uint32_t i = 0; i < bih.height; i++) {
for (uint32_t j = 0; j < bih.width; j++) {
uint32_t index = i * bih.width + j;
fread(&p[index], 1, sizeof(p[0]), fin);
p[index].blue = 255 - p[index].blue;
p[index].green = 255 - p[index].green;
p[index].red = 255 - p[index].red;
}
uint32_t k = (bih.width * i) - 1;
uint32_t c = 0 + (i * bih.width);
if ( i == 0) {
k = bih.width - 1;
}
while( (c * bih.width) < (k * bih.width))
{
temp = p[c];
p[c] = p[k];
p[k] = temp;
c++;
k--;
}
fseek(fin, padding_bytes, SEEK_CUR);
}
fclose(fin);
fout = fopen(argv[2], "wb");
if(nullptr == fout) {
perror(argv[2]);
return -5;
}
if( sizeof(BitmapFileHeader) != fwrite(
&bfh,
1,
sizeof(bfh),
fout
)) {
printf("Unable to write bitmap file header.\n");
return -6;
}
if( sizeof(BitmapInfoHeader) != fwrite(
&bih,
1,
sizeof(bih),
fout
)) {
printf("Unable to write bitmap info header.\n");
return -7;
}
fseek(fout, bfh.offset, SEEK_SET);
for (uint32_t i = 0; i < bih.height; i++) {
for (uint32_t j = 0; j < bih.width; j++) {
uint32_t index = i * bih.width + j;
fwrite(&p[index], 1, sizeof(p[0]), fout);
}
fseek(fout, padding_bytes, SEEK_CUR);
}
if (padding_bytes > 0) {
fseek(fout, -1, SEEK_CUR);
fputc('\0', fout);
}
fclose(fout);
delete[] p;
return 0;
}
解决方案
你的界限错了,应该是c = i * bih.width; k = (i + 1) * bih.width - 1;
。
您也可以使用它std::reverse
来执行此操作:
std::reverse(p + i * bih.width, p + (i + 1) * bih.width); // Exclusive end, so no -1
推荐阅读
- angular - 应用程序登录 IONIC 3 后如何自动启用 GPS?
- javascript - 在javascript-ajax中提交表单时如何显示进度条
- php - 为什么dompdf有时会生成空白pdf?
- webrtc - webRTC:视频流在本地播放但不在远程播放
- jtag - JLink 调试器 - 物理连接问题(microSD 卡插槽 + DIY jtag->microsd 适配器)
- c++ - C++ 复制构造函数需要帮助和错误不断发生。错误是在“ex”中请求“ex”,它是非类类型“int*”
- post - laravel8中的发布请求不起作用
- html - Bootstrap Typography Fail 1 - 没有找到合适的大写和反向值的类属性
- jira - JQL 在过去一周的开始日没有未解决的问题,在该周的结束日没有关闭的问题
- html - 如何在顺风中以自定义高度居中网格行中的元素?