Resizing an image

Hi,

I'm back with an other problem in my program. I load an interleaved raw image with 8 bit RGB and, as previously suggested in this forum, i load it with this code:

1
2
3
4
unsigned char* bufferImmagine=new unsigned char[dimX*dimY*3];

fread(bufferImmagine,dimX*dimY*3,1,file);
fclose(file);	


where dimX and dimY are the dimension of width and heigth and 3 is used for the three colors red, green and blue. But now I want that user can decide the dimensions of the elaborated output image, so I need an algorithm to resize the image (for example my input image is 640*480 and my output is 1280*800 or my input is 640*480 and my output is 400*200). The algorithm i thought gives me a black image as output...and sincerly I'm becoming crazy cause I can't find a better resize algorithm. Any idea? Could you help me?

My algorithm is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void ImmagineDestinazione::scalaImmagine(int rapportoX, int rapportoY, int x, int y) {
	int u,v;
	unsigned char* bufferTemporaneo=new unsigned char [dimX*dimY*3];
	for (int i=0;i<dimX*dimY*3;i++) {
		bufferTemporaneo[i]=bufferImmagine[i];
		bufferImmagine[i]=0;
	}
	
	for (int lung=0; lung<x; lung++) {
		for (int larg=0; larg<y; larg++) {
			u=lung*rapportoX;
	                v=larg*rapportoY;
                     bufferImmagine[u+(v*dimX)]=bufferTemporaneo[lung+(larg*x)];
		}
	}
}


where x and y are my initial dimensions and dimX and dimY are the final dimensions.

Resizing a digital image is often called image resampling. Conventional algorithms include Nearest Neighbor, Bilinear, and Bicubic interpolation. I may have some code at home that I can post, but in the mean time you should be able to search for some info on the above.
I think bilinear one will be great. If you have time and desire, could you post your code? I think my problem dipends I save my image on a unique big dynamic array :(
Giamma,

I have not found any code that I am able to post (due to IP rights), if I get time I will try to produce some code to resisze/resample your data (It may take a while), maybe someone else has some code?

Oh, no problem...anyway...could you view my code and tell me what it's wrong?
Have a look at the following code, I think it dose what you ar trying to do:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include<iostream>

class RawBitMap
{
public:
    RawBitMap():_data(NULL), _width(0),_height(0)
    {};

    bool Initialise()
    {
        // Set a basic 2 by 2 bitmap for testing.
        //
        if(_data != NULL)
            delete[] _data;

        _width = 2;
        _height = 2;    
        _data = new unsigned char[ GetByteCount() ];
        
        //
        _data[0] = 0;   // Pixels(0,0) red value
        _data[1] = 1;   // Pixels(0,0) green value
        _data[2] = 2;   // Pixels(0,0) blue value
        _data[3] = 253; // Pixels(1,0)
        _data[4] = 254;
        _data[5] = 255;
        _data[6] = 253; // Pixels(0,1)
        _data[7] = 254;
        _data[8] = 255;
        _data[9] = 0;   // Pixels(1,1)
        _data[10] = 1;
        _data[11] = 2;  

        return true;
    }

    // Perform a basic 'pixel' enlarging resample.
    bool Resample(int newWidth, int newHeight)
    {
        if(_data == NULL) return false;
        //
        // Get a new buuffer to interpolate into
        unsigned char* newData = new unsigned char [newWidth * newHeight * 3];

        double scaleWidth =  (double)newWidth / (double)_width;
        double scaleHeight = (double)newHeight / (double)_height;

        for(int cy = 0; cy < newHeight; cy++)
        {
            for(int cx = 0; cx < newWidth; cx++)
            {
                int pixel = (cy * (newWidth *3)) + (cx*3);
                int nearestMatch =  (((int)(cy / scaleHeight) * (_width *3)) + ((int)(cx / scaleWidth) *3) );
                
                newData[pixel    ] =  _data[nearestMatch    ];
                newData[pixel + 1] =  _data[nearestMatch + 1];
                newData[pixel + 2] =  _data[nearestMatch + 2];
            }
        }

        //
        delete[] _data;
        _data = newData;
        _width = newWidth;
        _height = newHeight; 

        return true;
    }

    // Show the values of the Bitmap for demo.
    void ShowData()
    {
        std::cout << "Bitmap data:" << std::endl;
        std::cout << "============" << std::endl;
        std::cout << "Width:  " << _width  << std::endl;
        std::cout << "Height: " << _height  << std::endl;
        std::cout << "Data:" << std::endl;

        for(int cy = 0; cy < _height; cy++)
        {
            for(int cx = 0; cx < _width; cx++)
            {
                int pixel = (cy * (_width *3)) + (cx*3);
                std::cout << "rgb(" << (int)_data[pixel] << "," << (int)_data[pixel+1] << "," << (int)_data[pixel+2] << ") ";
            }
            std::cout << std::endl;
        }
        std::cout << "_________________________________________________________" << std::endl;
    }


    // Return the total number of bytes in the Bitmap.
    inline int GetByteCount()
    {
        return (_width * _height * 3);
    }
    
private:
    int _width;
    int _height;
    unsigned char* _data;

};


int main(int argc, char* argv[])
{
	RawBitMap bitMap;

    bitMap.Initialise();
    bitMap.ShowData();

    if (!bitMap.Resample(4,4))
        std::cout << "Failed to resample bitMap:" << std::endl ; 
    bitMap.ShowData();

    bitMap.Initialise();
    if (!bitMap.Resample(3,3))
        std::cout << "Failed to resample bitMap:" << std::endl ;
    bitMap.ShowData();
    

    return 0;
}


It's not very elagant but...
Many thanks...your code works very fine...i have adapted mine code with yours and now i can resize my image. My mistake was in u and v that I have substituted with
1
2
int pixel = (cy * (newWidth *3)) + (cx*3);
int nearestMatch =  (((int)(cy / scaleHeight) * (_width *3)) + ((int)(cx / scaleWidth) *3) );


Thanks a lot...if you will come to Italy, you'll have a beer paid =)
I'm glad to be of help.

Where about in Italy are you? ;0) I have friend of the family that live in Formatza(?), somewhere near Domodossala. I have been to the Tuscany area, around Padua, San Gimignano, Florance, Venice...It's very nice there.


I live in Padova (in English it's Padua)
Topic archived. No new replies allowed.