صفيف من المؤشرات إلى هياكل RGB يشير دائمًا إلى البكسل الأول

-1

bmp.h

// BMP-related data types based on Microsoft's own

#include <stdint.h>

// aliases for C/C++ primitive data types
// https://msdn.microsoft.com/en-us/library/cc230309.aspx
typedef uint8_t  BYTE;
typedef uint32_t DWORD;
typedef int32_t  LONG;
typedef uint16_t WORD;

// information about the type, size, and layout of a file
// https://msdn.microsoft.com/en-us/library/dd183374(v=vs.85).aspx
typedef struct
{
    WORD bfType;
    DWORD bfSize;
    WORD bfReserved1;
    WORD bfReserved2;
    DWORD bfOffBits;
} __attribute__((__packed__))
BITMAPFILEHEADER;

// information about the dimensions and color format
// https://msdn.microsoft.com/en-us/library/dd183376(v=vs.85).aspx
typedef struct
{
    DWORD biSize;
    LONG biWidth;
    LONG biHeight;
    WORD biPlanes;
    WORD biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
} __attribute__((__packed__))
BITMAPINFOHEADER;

// relative intensities of red, green, and blue
// https://msdn.microsoft.com/en-us/library/dd162939(v=vs.85).aspx
typedef struct
{
    BYTE rgbtBlue;
    BYTE rgbtGreen;
    BYTE rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;

تغيير الحجم ج

#include <stdio.h>
#include <stdlib.h>

#include "bmp.h"

int main(int argc, char *argv[])
{
    // ensure proper usage
    if (argc != 4)
    {
        fprintf(stderr, "Usage: ./resize n infile outfile\n");
        return 1;
    }

// remember factor and filenames
int factor = atoi(argv[1]);
char *infile = argv[2];
char *outfile = argv[3];

// open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
    fprintf(stderr, "Could not open %s.\n", infile);
    return 2;
}

// open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL)
{
    fclose(inptr);
    fprintf(stderr, "Could not create %s.\n", outfile);
    return 3;
}

// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
    bi.biBitCount != 24 || bi.biCompression != 0)
{
    fclose(outptr);
    fclose(inptr);
    fprintf(stderr, "Unsupported file format.\n");
    return 4;
}

// update outfile's BITMAPINFOHEADER
BITMAPINFOHEADER obi = bi;
obi.biWidth *= factor;
obi.biHeight *= factor;

// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);

// write outfile's BITMAPINFOHEADER
fwrite(&obi, sizeof(BITMAPINFOHEADER), 1, outptr);

// determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// determine outfile's padding
int out_padding = (4 - (obi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// remember pixels in an array
RGBTRIPLE * array[obi.biWidth];

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    array[0] = NULL;
    int idx = 0;

    printf("----------------------\nReading from file.\n----------------------\n");
    // iterate over pixels in scanline
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;

        // read RGB triple from infile
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

        // write to array n times
        for(int k = 0; k < factor; k++)
        {
            array[idx] = &triple;
            printf("scanline n°%d, pixel n°%d, array[%d] = %p, blue: %i, green: %i, red: %i\n", i, j, k, array[k], triple.rgbtBlue, triple.rgbtGreen, triple.rgbtRed);
            ++idx;
        }
    }
    printf("\nNow writing to outfile...\n\n");
    // for n times
    for (int x = 0; x < factor; x++)
    {
        // write array to outfile
        for(int y = 0; y < obi.biWidth; y++)
        {
            fwrite(array[y], sizeof(RGBTRIPLE), 1, outptr);
            printf("scanline n°%d, array[%d] = %p\n", i, y, array[y]);
        }

        // write padding to outfile
        for(int k = 0; k < out_padding; k++)
        {
            fputc(0x00, outptr);
        }
    }

    // skip over padding, if any
    fseek(inptr, padding, SEEK_CUR);
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;
}

ملف الإدخال

ملف إلاخراج

أحاول كتابة برنامج بلغة C يقوم بتغيير حجم ملفات BMP. يأخذ البرنامج ثلاث حجج (ملف BMP صغير ، واسم ملف BMP كبير يتم إنشاؤه من BMP الصغير ، وعامل يتم من خلاله زيادة BMP الصغير).

للقيام بذلك ، أقوم بتخزين كل مسح للبكسل ليتم تكراره n مرة في صفيف من المؤشرات التي سأستخدمها للكتابة إلى ملف الإخراج الجديد. مشكلتي هي أنه على الرغم من تغير قيم RGB عندما تصل إلى وحدات البكسل البيضاء ، فإن كل مؤشر له نفس العنوان. وبالتالي ، فإن ملف الإخراج هو مجرد مربع أخضر بدلاً من مربع أخضر مع بكسل أبيض في المنتصف. لا يمكنني معرفة السبب ، هل يمكن لأي شخص أن يشرح لماذا يكون العنوان دائمًا هو نفسه

1 إجابة

1
افضل جواب
RGBTRIPLE * array[obi.biWidth];

قم بتغيير هذا إلى RGBTRIPLE array[obi.biWidth]; أو RGBTRIPLE *array = malloc(...) كما هو مقترح في التعليقات.

يتغيرون array[idx] = &triple; إلى array[idx] = triple;

for(int y = 0; y < obi.biWidth; y++)
{
    fwrite(array[y], sizeof(RGBTRIPLE), 1, outptr);
}

يمكنك كتابة المصفوفة بأكملها بدلاً من كتابة عنصر واحد في كل مرة:

RGBTRIPLE *array = malloc(obi.biWidth * sizeof(RGBTRIPLE));
for(int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    for(int j = 0; j < bi.biWidth; j++)
    {
        RGBTRIPLE triple;
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

        for(int k = 0; k < factor; k++)
            array[j * factor + k] = triple;
    }

    for(int x = 0; x < factor; x++)
    {
        fwrite(array, sizeof(RGBTRIPLE), obi.biWidth, outptr);

        for(int k = 0; k < out_padding; k++)
            fputc(0x00, outptr);
    }

    fseek(inptr, padding, SEEK_CUR);
}
free(array);

يجب عليك أيضًا تغيير قيمة BITMAPFILEHEADERbfSize :

int out_padding = (4 - (obi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
bf.bfSize = 54 + (obi.biWidth * 3 + out_padding) * obi.biHeight;//total file size
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
:مؤلف
فوق
قائمة طعام