Advertisement

Question about enlarging a bitmap.

Started by February 12, 2020 10:01 PM
20 comments, last by Josheir 4 years, 9 months ago

I have an eight by eight bitmap box (24 bit) with four colors, one in each quadrant. I am trying to enlarge it to sixteen by sixteen. I am concentrating on the blue and green sections. The first attempt looks like this:

The second attempt is supposed to double each row and results in this:

The pixels do enlarge but the rows are one color, not blue and green.

The code is as follows:

if ((i % 12 == 0) && (i != 0))
            {

                if (wenthere == 2)
                {
                    wenthere = 0;
                    i = i - 12;

                }
                wenthere++;
            }

And the full code is here:

while (1)
    {
        count++;
        i = fgetc(file);
        if (feof(file)) {
            fclose(file);
            break;
        }

    }
   
   
    i = 0;
    file = fopen(r_path, "r");
    fseek(file, 54, SEEK_SET);
    int var3 = 0;
    do {
        var3 = fgetc(file);
        if (feof(file)) {
            fclose(file);
            break;
        }
        allinthexdecimal[i] = var3;
        
        i++;
        element_index++;


    } while (1);

    int j = 0;
    i = 0;
    int wenthere = 2;
        
       //hex image is 822 - 54 = 768 % 6 % 2 = 64
        for (int z = 0; z < 64; z++)
        {
            allnewinthexdecimal[j] = allinthexdecimal[(i)];

            std::cout << allnewinthexdecimal[j] << "  ";

            allnewinthexdecimal[(j + 1)] = allinthexdecimal[(i + 1)];

            std::cout << allnewinthexdecimal[j + 1] << "  ";

            allnewinthexdecimal[(j + 2)] = allinthexdecimal[(i + 2)];

            std::cout << allnewinthexdecimal[j + 2] << "             ";

            allnewinthexdecimal[(j + 3)] = allinthexdecimal[(i)];

            std::cout << allnewinthexdecimal[j + 3] << "  ";

            allnewinthexdecimal[(j + 4)] = allinthexdecimal[(i + 1)];

            std::cout << allnewinthexdecimal[j + 4] << "  ";

            allnewinthexdecimal[(j + 5)] = allinthexdecimal[(i + 2)];

            std::cout << allnewinthexdecimal[j + 5] << "             ";

            i = i + 3;
            j = j + 6;
           
            if ((i % 12 == 0) &amp;&amp; (i != 0))
            {

                if (wenthere == 2)
                {
                    wenthere = 0;
                    i = i - 12;

                }
                wenthere++;
            }
        }
    

    i = 96;
    
    
    for (int z = 0; z < 64; z++)
    {
        
        allnewinthexdecimal[j + 0] = allinthexdecimal[i + 0];
          
        allnewinthexdecimal[(j + 1)] = allinthexdecimal[(i + 1)];
            
        allnewinthexdecimal[(j + 2)] = allinthexdecimal[(i + 2)];

        
        allnewinthexdecimal[(j + 3)] = allinthexdecimal[(i+0)];
        
        allnewinthexdecimal[(j + 4)] = allinthexdecimal[(i + 1)];
        
        allnewinthexdecimal[(j + 5)] = allinthexdecimal[(i + 2)];
         
        i = i + 3;
        j = j + 6;

    }
   

Any guidance or help would be appreciated.

Josheir

Better images :

Advertisement

You know that you are allowed to nest for-loops?

std::cout and “ ” look like you are doing text-files, not bitmap? Doesn't c stand for character here?

I wanted to simplify, so I didn't nest, this was not exactly my first attempt. The std::couts don't produce hex, it was just a quick way to see the repeating numbers. The program does indeed create and read a bitmap. What I was trying to do was duplicate each row with the two different colors. Oh, and the two black pixels are being used for testing purposes.

Josheir

Do I need to show more code?

This is the eight by eight :

Advertisement

The code is really hard to interpret, you might want to try to explain the pieces and what you intend them to do.

The types of the variables here are not visible. A few things:

* Read the file in binary mode! ("rb")
* Also, why are you reading the file byte per byte? You could to a block read (fread)

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

I may be old, but with bitmaps I always found it easy just to put them onto the screen. Once in a (not game related and very boring) program there needed to be an icon in a database created dynamically and I jumped onto that topic and hacked together some pascal code to create a bitmap. Just copy the header from a template. The rest is right there on screen.

I have an internal optimizer in my head. If I read unrolled loops I doze away after the second line. Sorry.

Following that code is really difficult. Things like “int wenthere = 2;” and “i = 96” are really not obvious.

Also you don't appear to properly parse the bitmap, do check that your code to read and write bitmaps is correct. Headers can be different lengths with a few optional sections and pixels different formats so just have to trust the 54byte seek is correct for this file. And there can be data after the pixel array. Also the pixel array can have padding for each row.

In the general case if was writing a scale up/down transform I definitely start by getting the input and output into a simple format. Note that BMP (and some other formats) actually store the bottom row first but for operations like this it doesn't really matter which way you think of it, or if you flip it or not, and also might need to consider different pixel order (e.g. RR GG BB vs BB GG RR, or alpha/padding, different channel depths, etc.), pelleted color, etc. You might choose to just reject files with some of these, but should check and probably want to handle the common cases.

e.g. assuming I am only dealing with 8bit per channel, 24bit RGB, I might have.

struct Image
{
    int width; // width in pixels
    int pitch; // row length in bytes (e.g. BMP files I believe pad rows to 32bits, even though each pixel is 24bits)
    int height; // height in pixels
    std::vector<unsigned char> data; // or unique_ptr or such. should be pre-sized to least pitch*height bytes.
};

And then loop over the output image to determine what to make each pixel.

Now given a 24bit per pixel format, I think this does something like you want.

void scale(const Image &amp;in, Image &amp;out)
{
    for (int y = 0; y < out.height; ++y) // each output row
    {
        for (int x = 0; x < out.width; ++x) // each output pixel
        {
            int sx = x * in.width / out.width;
            int sy = y * in.height / out.height;
            out.data[y * out.pitch + x * 3 + 0] = in.data[sy * in.pitch + sx * 3 + 0];
            out.data[y * out.pitch + x * 3 + 1] = in.data[sy * in.pitch + sx * 3 + 1];
            out.data[y * out.pitch + x * 3 + 2] = in.data[sy * in.pitch + sx * 3 + 2];
        }
    }
}

Well, I am trying to wrap my head around this one. I am confused by the padding. when I look at this Microsoft Paint sixteen by sixteen and eight by eight I am not understanding where the padding is.

First, the images are like this:

And the two hex displays that I need explained are here:

8 by 8:

16 by 16 (partial):

I am asking because I am having trouble with the sample code. I am pretty sure the problem is the “pitch.”

This topic is closed to new replies.

Advertisement