如何反转数组的一部分?

问题描述 投票:0回答:1

我正在编写一个将位图文件读入内存的程序。但是,当我将其读入内存时,我正在进行一些更改。首先,我要反转像素的颜色。我设法使这个工作。现在,我尝试在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 * 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);

下面是我的整个程序,如果需要的话。

#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++ arrays sorting binaryfiles
1个回答
0
投票

您的界限错误,应该是c = i * bih.width; k = (i + 1) * bih.width - 1;

您也可以使用std::reverse执行此操作:

std::reverse
© www.soinside.com 2019 - 2024. All rights reserved.