Hello fellow programmers. I'm new to the forum so please bear with me.
What I am trying to achieve is taking a loaded image from file(e.g. background wallpaper image 4000x2250) and scale it down to native resolution of 1360x768. In the same fashion as a modern OS when you set a wallpaper image for your desktop.
typedef struct {
UINT8 Blue;
UINT8 Green;
UINT8 Red;
UINT8 Reserved;
} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
typedef EFI_GRAPHICS_OUTPUT_BLT_PIXEL GUI_PIXEL;
typedef struct {
UINT32 Width;
UINT32 Height;
BOOLEAN HasAlpha;
GUI_PIXEL *PixelData;
} GUI_IMAGE;
GUI_IMAGE* ReduceImage(GUI_IMAGE* image)
{
UINT32 resizeWidth = image->Width / 2;
UINT32 resizeHeight = image->Height / 2;
UINT32 x;
UINT32 y;
UINT32 row = 0;
UINT32 column = 0;
GUI_IMAGE *NewImage;
NewImage = AllocateZeroPool(sizeof(GUI_IMAGE));
if (NewImage == NULL)
{
return NULL;
}
NewImage->PixelData = AllocateZeroPool(resizeWidth * resizeHeight *
sizeof(GUI_PIXEL));
if (NewImage->PixelData == NULL)
{
FreePool(NewImage);
return NULL;
}
NewImage->Width = resizeWidth;
NewImage->Height = resizeHeight;
NewImage->HasAlpha = TRUE;
for(y = 0; y < resizeHeight - 1; y++)
{
for(x = 0; x < resizeWidth - 1; x++)
{
NewImage->PixelData[(resizeWidth) * y + x] = image->PixelData[(image->Width) * row + column];
column += 2;
}
row += 2;
column = 0;
}
return NewImage;
}
Thank you for all the help! I figured it out.
// macro to return -/+ half value
#define RoundValue(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
GUI_IMAGE* ScaleImage(GUI_IMAGE* image)
{
float ratio; // >1 is enlarging(e.g. 1.1), <1 is reducing(e.g. 0.4)
UINT32 resWidth;
UINT32 resHeight;
UINT32 x;
UINT32 y;
UINT32 x_in;
UINT32 y_in;
GUI_IMAGE *NewImage;
// get screen resolution for x and y
GetResolution(&resWidth, &resHeight);
// calculate ratio
ratio = (float)resWidth / (float)image->Width;
// allocate space for the new image
NewImage = AllocateZeroPool(sizeof(GUI_IMAGE));
if (NewImage == NULL)
{
// if no allocation, return NULL
return NULL;
}
// allocate space for pixel data
NewImage->PixelData = AllocateZeroPool(resWidth * resHeight * sizeof(GUI_PIXEL));
if (NewImage->PixelData == NULL)
{
// if no allocation, return NULL
FreePool(NewImage);
return NULL;
}
// set image attributes
NewImage->Width = resWidth;
NewImage->Height = resHeight;
NewImage->HasAlpha = TRUE;
// loop through x and y coordinates of the entire screen
for(y = 0; y < resHeight; y++)
{
for(x = 0; x < resWidth; x++)
{
// calculate target area and set new pixel data from original data
x_in = RoundValue((float)x / ratio);
y_in = RoundValue((float)y / ratio);
NewImage->PixelData[resWidth * y + x] = image->PixelData[image->Width * y_in + x_in];
}
}
// return new image
return NewImage;
}