Я пытаюсь изменить размер изображения с помощью билинейной техники, которую я нашел Вот но я не вижу ничего, кроме черного изображения.
Итак, во-первых, мое изображение расшифровывается с LodePNG и пиксели входят в vector<unsigned char>
переменная. Там написано, что они хранятся как RGBARGBA, но когда я попытался применить изображение к окну X11, я понял, что они хранятся как BGRABGRA. Я не знаю, является ли API X11, который изменяет порядок, или декодером LodePNG. В любом случае, прежде чем я преобразую BGR в RGB:
// Here is where I have the pixels stored
vector<unsigned char> Image;
// Converting BGRA to RGBA, or vice-versa, I don't know, but it's how it is shown
// correctly on the window
unsigned char red, blue;
unsigned int i;
for(i=0; i<Image.size(); i+=4)
{
red = Image[i + 2];
blue = Image[i];
Image[i] = red;
Image[i + 2] = blue;
}
Итак, сейчас я пытаюсь изменить размер изображения, прежде чем применить его к окну. Размер будет размером окна (растяните его).
Сначала я пытаюсь преобразовать RGBA в значения int, например:
vector<int> IntImage;
for(unsigned i=0; i<Image.size(); i+=4)
{
IData.push_back(256*256*this->Data[i+2] + 256*this->Data[i+1] + this->Data[i]);
}
Теперь у меня есть эта функция по указанной выше ссылке, которая должна выполнять интерполяцию:
vector<int> resizeBilinear(vector<int> pixels, int w, int h, int w2, int h2) {
vector<int> temp(w2 * h2);
int a, b, c, d, x, y, index ;
float x_ratio = ((float)(w-1))/w2 ;
float y_ratio = ((float)(h-1))/h2 ;
float x_diff, y_diff, blue, red, green ;
for (int i=0;i<h2;i++) {
for (int j=0;j<w2;j++) {
x = (int)(x_ratio * j) ;
y = (int)(y_ratio * i) ;
x_diff = (x_ratio * j) - x ;
y_diff = (y_ratio * i) - y ;
index = (y*w+x) ;
a = pixels[index] ;
b = pixels[index+1] ;
c = pixels[index+w] ;
d = pixels[index+w+1] ;
// blue element
// Yb = Ab(1-w)(1-h) + Bb(w)(1-h) + Cb(h)(1-w) + Db(wh)
blue = (a&0xff)*(1-x_diff)*(1-y_diff) + (b&0xff)*(x_diff)*(1-y_diff) +
(c&0xff)*(y_diff)*(1-x_diff) + (d&0xff)*(x_diff*y_diff);
// green element
// Yg = Ag(1-w)(1-h) + Bg(w)(1-h) + Cg(h)(1-w) + Dg(wh)
green = ((a>>8)&0xff)*(1-x_diff)*(1-y_diff) + ((b>>8)&0xff)*(x_diff)*(1-y_diff) +
((c>>8)&0xff)*(y_diff)*(1-x_diff) + ((d>>8)&0xff)*(x_diff*y_diff);
// red element
// Yr = Ar(1-w)(1-h) + Br(w)(1-h) + Cr(h)(1-w) + Dr(wh)
red = ((a>>16)&0xff)*(1-x_diff)*(1-y_diff) + ((b>>16)&0xff)*(x_diff)*(1-y_diff) +
((c>>16)&0xff)*(y_diff)*(1-x_diff) + ((d>>16)&0xff)*(x_diff*y_diff);
temp.push_back(
((((int)red)<<16)&0xff0000) |
((((int)green)<<8)&0xff00) |
((int)blue) |
0xff); // hardcode alpha ;
}
}
return temp;
}
и я использую это так:
vector<int> NewImage = resizeBilinear(IntData, image_width, image_height, window_width, window_height);
который должен вернуть мне вектор RGBA измененного размера изображения. Теперь я перехожу обратно в RGBA (от int)
Image.clear();
for(unsigned i=0; i<NewImage.size(); i++)
{
Image.push_back(NewImage[i] & 255);
Image.push_back((NewImage[i] >> 8) & 255);
Image.push_back((NewImage[i] >> 16) & 255);
Image.push_back(0xff);
}
и я получаю черное окно (цвет фона по умолчанию), поэтому я не знаю, что мне не хватает. Если я закомментирую строку, где я получаю новое изображение и просто преобразовать обратно в RGBA, IntImage
Я получаю правильные значения, поэтому я не знаю, если это испорченный RGBA / int <> Int / RGBA. Я просто потерянный сейчас. Я знаю, что это можно оптимизировать / упростить, но сейчас я просто хочу, чтобы это работало.
Доступ к массиву в вашем коде неверен:
vector<int> temp(w2 * h2); // initializes the array to contain zeros
...
temp.push_back(...); // appends to the array, leaving the zeros unchanged
Вы должны переписать вместо добавления; для этого рассчитаем положение массива:
temp[i * w2 + j] = ...;
В качестве альтернативы, инициализируйте массив в пустое состояние и добавьте ваши вещи:
vector<int> temp;
temp.reserve(w2 * h2); // reserves some memory; array is still empty
...
temp.push_back(...); // appends to the array
Других решений пока нет …