In an earlier post we looked at converting an image to 16 bit 5:6:5 format for direct copying to framebuffer. The obvious drawback of that approach is the requirement on the image size to exactly match the display/framebuffer size (or the width at least).
Modifying the PPM reading code to read into an image object in memory (I chose to use the struct fb_image from linux/fb.h as teh image object) and combining that with the familiar framebuffer drawing code (put_pixel_RGB565 from part 6)
Make sure you have a 24 bit PPM image file to start with - convert one from for example PNG using pngtopnm (any bit depth source file should do) - and make sure the image fits the screen (no bounds checking in the code). Then compile and run:
...
int read_ppm(char *fpath, struct fb_image *image) {
...
image->data = malloc(width * height * bytes_per_pixel);
...
// store pixel in memory
unsigned int pix_offset = (y * width + x ) * bytes_per_pixel;
*((unsigned short *)(image->data + pix_offset)) = rgb565;
...
void draw(struct fb_image *image) {
int y;
int x;
unsigned char rgb[3];
for (y = 0; y < image->height; y++) {
for (x = 0; x < image->width; x++) {
// get pixel from image
unsigned int img_pix_offset = (y * image->width + x) * 2;
unsigned short c =
*(unsigned short *)(image->data + img_pix_offset);
// plot pixel to screen
unsigned int fb_pix_offset =
x * 2 + y * finfo.line_length;
*((unsigned short*)(fbp + fb_pix_offset)) = c;
}
}
}
...
int main(int argc, char* argv[])
{
// read the image file
int ret = read_ppm(argv[1], &image);
if (ret != 0) {
printf("Reading image failed.\n");
return ret;
}
...
gcc -O2 -o ppmtofbimg ppmtofbimg.c ./ppmtofbimg test24.ppm
Full source and a test image (test24.ppm) in GitHub.




