Changing BPP in XImage


 
Thread Tools Search this Thread
Top Forums Programming Changing BPP in XImage
# 1  
Old 12-20-2010
Changing BPP in XImage

im trying to take a 24 BPP screen cap and save it to bitmap, but seems like it XImage is always 32 BPP, the value 0x00FFFFFF supposed to be 24 !

whenever i change bmpInfoHeader.biBitCount to 24, the image gets messed up..

here is the code im using

Code:
typedef struct tagBITMAPFILEHEADER {
	WORD    bfType;
	DWORD   bfSize;
	WORD    bfReserved1;
	WORD    bfReserved2;
	DWORD   bfOffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER{
	DWORD  biSize;
	LONG   biWidth;
	LONG   biHeight;
	WORD   biPlanes;
	WORD   biBitCount;
	DWORD  biCompression;
	DWORD  biSizeImage;
	LONG   biXPelsPerMeter;
	LONG   biYPelsPerMeter;
	DWORD  biClrUsed;
	DWORD  biClrImportant;
} BITMAPINFOHEADER;

void saveXImageToBitmap(XImage *pImage)
{
	BITMAPFILEHEADER bmpFileHeader;
	BITMAPINFOHEADER bmpInfoHeader;
	FILE *fp;
	static int cnt = 0;
	int dummy;
	char filePath[255];

	memset(&bmpFileHeader, 0, sizeof(BITMAPFILEHEADER));
	memset(&bmpInfoHeader, 0, sizeof(BITMAPINFOHEADER));
	bmpFileHeader.bfType = 0x4D42;
	bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + pImage->width*pImage->height*4;
	bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
	bmpFileHeader.bfReserved1 = 0;
	bmpFileHeader.bfReserved2 = 0;

	bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmpInfoHeader.biWidth = pImage->width;
	bmpInfoHeader.biHeight = pImage->height;
	bmpInfoHeader.biPlanes = 1;
	bmpInfoHeader.biBitCount = 32;
	dummy = (pImage->width * 3) % 4;
	if((4-dummy)==4)
		dummy=0;
	else
		dummy=4-dummy;
	bmpInfoHeader.biSizeImage = ((pImage->width*3)+dummy)*pImage->height;
	bmpInfoHeader.biCompression = 0;
	bmpInfoHeader.biXPelsPerMeter = 0;
	bmpInfoHeader.biYPelsPerMeter = 0;
	bmpInfoHeader.biClrUsed = 0;
	bmpInfoHeader.biClrImportant = 0;

	sprintf(filePath, "bitmap%d.bmp", cnt++);
	fp = fopen(filePath,"wb");

	if(fp == NULL)
		return;

	fwrite(&bmpFileHeader, sizeof(bmpFileHeader), 1, fp);
	fwrite(&bmpInfoHeader, sizeof(bmpInfoHeader), 1, fp);
	fwrite(pImage->data, 4*pImage->width*pImage->height, 1, fp);
	fclose(fp);
}

void screen()
{
    unsigned int height, width;
    unsigned int unused;
    int unused_int;
    Display *dpy = XOpenDisplay(NULL);
    Window root = DefaultRootWindow(dpy);
    XGetGeometry(dpy, root, (Window *) &unused, &unused_int, &unused_int, &width, &height, &unused, &unused);
    XImage *img=XGetImage(dpy, root, 0, 0, width, height, 0x00ffffff, ZPixmap);
    SaveXImageToBitmap(img);
    XDestroyImage(img);
    XCloseDisplay(dpy);
}

thanks..
# 2  
Old 12-20-2010
Quote:
Originally Posted by JonhyM
im trying to take a 24 BPP screen cap and save it to bitmap, but seems like it XImage is always 32 BPP, the value 0x00FFFFFF supposed to be 24 !

whenever i change bmpInfoHeader.biBitCount to 24, the image gets messed up..
Changing the header doesn't change the data. 0x00ffffff is 32-bit, count the bytes, so if you still write it raw you're still writing 32-bit data. Instead of writing 0x00ffffff for every pixel, you should be skipping one byte and writing 0xffffff.

Which is going to be a fair bit more complicated: It'll mean doing pointer arithmetic to read the data you want.

Code:
enum
{
        // Adjust these to match what your data actually is
        R_32 = 0,
        G_32 = 1,
        B_32 = 2,
        A_32 = 3,

        R_24 = 0,
        G_24 = 1,
        B_24 = 2,
};

const unsigned char *raw=(const unsigned char *)rawdata;
unsigned char *lineout=malloc(width * 3);
for(y=0; y<height; y++)
{
        const unsigned char *line=raw + (width * y);
        unsigned char *ptr=lineout;
        int x;

        printf("pixel 0,%d = {%02x %02x %02x %02x}\n", y, line[0], line[1], line[2], line[3]);


        for(x=0; x<width; x++)
        {
                ptr[R_24]=line[R_32];
                ptr[G_24]=line[G_32];
                ptr[B_24]=line[B_32];
                line += 4;
                ptr += 3;
        }

        write(lineout, 3, width, outfile);
}

free(lineout);

Try making an ximage file with a known pixel value at 0,0 so you can see exactly what colors are what offsets.

This is very exact and tedious and will probably break if you compile it on a different architecture. I used sdl to make xtopng because it's already written all this junk for you. Smilie

Last edited by Corona688; 12-20-2010 at 05:43 PM.. Reason: done editing, I swear
# 3  
Old 12-20-2010
no other option? maybe XCreateImage?
# 4  
Old 12-20-2010
Do you really want to link all of X to convert a silly bitmap?
# 5  
Old 12-20-2010
im already linking it, for XGetImage
# 6  
Old 12-21-2010
I don't think XCreateImage does what you want. You'd best be prepared to accept whatever bit depth it gives you...
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Input value changing into 0

Hi, I am getting a strange problem in my production environment. Line in input file: Code: while read myline do echo $myline >> /home/aauytrf/PARM_FILE_NM.bak fi done < /home/aauytrf/PARM_FILE_NM.prm Output: 0 Here the input line is becoming 0. This is not happening to... (11 Replies)
Discussion started by: niba
11 Replies

2. UNIX for Dummies Questions & Answers

Changing different value to single value

I have a input file like this select column1,column2 from tablename where column3='1000000001'; select column1,column2 from tablename where column3='1000000002'; select column1,column2 from tablename where column3='1000000003'; select column1,column2 from tablename where column3='1000000004';... (4 Replies)
Discussion started by: nsuresh316
4 Replies

3. Shell Programming and Scripting

password changing

Hi all Im trying to learn the basics of bash and am struggling with some file manipulation. I am trying to run a script that once you have logged in allows you to change your password which is held (along with the corresponding username) in a different file called usernames. When i try to run my... (2 Replies)
Discussion started by: somersetdan
2 Replies

4. Shell Programming and Scripting

changing the permissions

HI, I wann give permissions to a folder which contains multiple folders..... how can i give permissions to all folder at a time tat means if i give permissions to main folder it the same permissions has to take on all the folders in the main folders how can i use one command to give... (1 Reply)
Discussion started by: nani1984
1 Replies

5. Shell Programming and Scripting

Changing Name of File

Write a shell program to replace the starting alphabet "a" with "k" for the file names in the current directory. Note : Change only the file names starting with "a". Rest of the file names remains unchanged. Homework. Replies deleted. Closed. (0 Replies)
Discussion started by: shashwat2691
0 Replies

6. Programming

Converting XImage to PNG

i was able to make a connection to X server and get a screen shot using XGetImage, now, im unable to save this XImage to any good format like PNG, i found a code that saves it to bitmap, but the resulted bitmap file is massive, is there anyway i can save this XImage to PNG directly? thanks; (7 Replies)
Discussion started by: JonhyM
7 Replies

7. UNIX for Dummies Questions & Answers

Changing / to - with vi

Hi just learning Unix in college now and this is my first post here, so I dunno if this goes here, or in the homework section technically. Anywho, trying to change all the / in a file into - using vi... i went into the command prompt, and put in :%s///-/g and it comes up with E488: Trailing... (2 Replies)
Discussion started by: SoVi3t
2 Replies

8. Shell Programming and Scripting

Changing userID and Changing group and GID

Hello, I want to write a ksh script about changing UID and changing group with GID. There are multiple servers i want to perform that job. linux1 linux2 linux3 linux4 linux5 ...... . . . . . 1.) How can i enter "password" in script rather asking me? I was trying this... ssh... (2 Replies)
Discussion started by: deal732
2 Replies

9. Solaris

changing password

Hi Someone logged on the system with a Normal user and changed the password , for this user , how can i know ? who changed the password from which terminal ? regards Georges (5 Replies)
Discussion started by: itsgeorge
5 Replies

10. IP Networking

Changing the mask

What is the command to change the mask to 255.255.255.0 The system was set up incorectly and the mask needs to be corrected (1 Reply)
Discussion started by: kkinnon
1 Replies
Login or Register to Ask a Question