Page 1 of 2

Image manipulation in C

Posted: Sun Aug 22, 2010 3:14 pm
by Zacariaz
After days of searching the net I've just about given up.

All I wanted was to be able to load an image, preferably from the clipboard, which apparently I also got working and then read and alter the pixels. That's it. Obviously, later on I'd like to save the data or something, but that's really not important at this point.

So, I searched the net and learned terms like HBITMAP, CF_BITMAP, CF:DIB, BITMAPINFO, BITMAPINFOHEADER, RGBWUAD, GetDIBits, etc...

But not once have I found anything which takes this back to basic and explains it from the beginning.

I mean, sure I got a HBITMAP with some data in it and if I use CF_DIB I can even read some data treating the variable like a simple array, but the data representation isn't as expected and it's probably not the right way to do things anyway.

Bottom line. this all seemed so simple to begin with, but apparently I was mistaken.

Now, I know someone will ask for some code so, though it really doesn't help anyone, here's some:

Code: Select all

#include <windows.h>

int main(int argc, char *argv[]) {
    // grabs image from clipboard, if any
    HBITMAP b;
    if(OpenClipboard(NULL) && IsClipboardFormatAvailable(CF_DIB)) {
        b = GetClipboardData(CF_DIB);
        CloseClipboard();
    return 0;
}
That's how far I've come and I don't suspect I'll get any further unless I get some help.

So if you know this subject, please try to guide me through it.

As I wrote earlier, all I need is to:
1. Load imagedata.
2. Manipulate the data
(and eventually)
3. save data.

Actually, since 1. is already done with, it seems, and 3. will be easy enough given easily accessible data, I really only need help with 2. ;)

Anyway, I know I've been kind of a bother in the past and I fully understand if this is too much, but then maybe a link to the proper tutorial, which I haven't been able to find in 3 days of intensive searching...


Thanks in advance.

Re: Image manipulation in C

Posted: Sun Aug 22, 2010 3:22 pm
by Candy
I would read directly from file. Open bitmap file, read in line by line (header contains stride & start of data, plus W and H). Then the image is upside down, flip it. Modify. Flip image again, write out with similar header.

If you use GIMP for creating the images, save in 32-bit mode. That way the data is perfectly consistent, there's no line-padding so you can just read in the entire buffer and pretend it's an image buffer of W*H flipped upside down. Saving is taking that header (pre-generate?), dumping data after it & modifying the header in 3 or so places.

Re: Image manipulation in C

Posted: Sun Aug 22, 2010 4:29 pm
by Hangin10
Is the pixel data in an odd format or something?

You could use GetDIBits() to retrieve the actual pixel data, or you could CreateCompatibleDC() and then select the bitmap object into the DC to draw on it (and presumably get the pixel data later, but I'm not quite sure if it needs some sort of flushing or something).

Since your searching turned up GetDIBits, describing exactly what problem you are having with the data representation would make it a lot easier to try to help.

Re: Image manipulation in C

Posted: Mon Aug 23, 2010 1:38 am
by Zacariaz
@Candy
Yes, that would be easier, but eventually I have to read from clipboard, so if it's possible, better start now.

@Hangin10
The reason that I haven't used GetDIBits() as similar, is not that they're not right for the pupose, but that they tale like a billion arguments, none of which I ubderstand. Yes, I need a tutorial for that too. So embaresing...


Anyway, thanks for the comeback.

Re: Image manipulation in C

Posted: Mon Aug 23, 2010 2:32 am
by pcmattman
The reason that I haven't used GetDIBits() as similar, is not that they're not right for the pupose, but that they tale like a billion arguments, none of which I ubderstand. Yes, I need a tutorial for that too. So embaresing...
If there's one thing Microsoft does well, it's definitely their API documentation (MSDN).

For changes to the data, Hangin10's suggestion is a good one. GDI Device Contexts (DC) are fairly easy to get the hang of too, just need to look around (try game development websites, they often have a fair bit on GDI graphics for 2D games).

You could also try "DIBs and Their Use", also on the MSDN.

Re: Image manipulation in C

Posted: Mon Aug 23, 2010 6:48 am
by Zacariaz
pcmattman wrote: If there's one thing Microsoft does well, it's definitely their API documentation (MSDN).

...

You could also try "DIBs and Their Use", also on the MSDN.
It is true that Microsoft's documentation is very professional, however, it's often written in a very hard to understand language, at least I think so, and with he lag of complete code examples it doesn't make it easier.

Like the GetDIBits() which takes 7 arguments, half of which I don't know what to do about, that alone is confusing enough. obviously one can read up on it, but given the simplicity of the operation needed one easily comes to the conclusion that this is not the method to use.

The point is that a simple code example would probably have done that I'd never have had to start this thread in the first place.

But enough said about Microsoft's otherwise excellent documentation. ;)


As for the last link, it may be exactly what I've been looking for, but it will take some time to read through it, so I'll have to get back on that.


Anyway, apart from me feeling like an idiot, all is good.


Thank you for the help.

Re: Image manipulation in C

Posted: Mon Aug 23, 2010 7:02 pm
by bewing
The MSDN documentation is decent, but unless you are simply looking up an argument list or something -- the code examples don't exist or are uninformative, the explanations of the functions are circular, M$ is constantly dropping functions in favor of other functions (and they don't give warning or a proper link) -- I could go on. Please, everybody, I hope you do better documenting your API in your own OS. Especially since, even with MSDN, you still need a big-@$$ book like Petzold to actually explain how to use the API for coding.

As far as bitmaps go: the problem is that there are at least 5 different possible headers (M$ keeps adding new fields, but preserves backward compatibility), and the bitstream can have at least 10 subformats, in general.

If all these clipboard images come from the same program, then they will have a consistent format, and you can hardcode it. It's probably a 24 or 32bit bottom-up BGR or BGRA DIB.
If you can find the beginning of the "bits" (which is what the headers are for), each pixel is probably 3 or 4 consecutive bytes, with the colors in BGR order, 8 bits per color.

Re: Image manipulation in C

Posted: Tue Aug 24, 2010 12:37 am
by Solar
There once was a helicopter crew that got lost in dense fog. Fuel was running low, and they were desperately looking for a place to land safely.

Suddenly, out of the fog a tall building emerged. People were staring at them out of their offices. The co-pilot quickly wrote on a piece of cardboard: "Where am I?", and held that to the cockpit window. One of the people in the fog-shrouded building held up a piece of paper that read: "In a helicopter."

The pilot nodded, banked, and quickly found the nearest airport.

After landing, his co-pilot asked him: "How did you know your way?" The pilot: "It had to be the Microsoft building. That answer was so very much like them: Technically correct, but completely unhelpful."

8)

Re: Image manipulation in C

Posted: Tue Aug 24, 2010 2:05 am
by Zacariaz
bewing wrote:If all these clipboard images come from the same program, then they will have a consistent format, and you can hardcode it. It's probably a 24 or 32bit bottom-up BGR or BGRA DIB.
If you can find the beginning of the "bits" (which is what the headers are for), each pixel is probably 3 or 4 consecutive bytes, with the colors in BGR order, 8 bits per color.

finding the beginning and end of the "pixels is easy enough, however the values I got was wrong. Now I've figured out that it's just because the picture is flipped horizontally, so that's all good.

However, although I can print the pixel values, that's just about the only thing I can do. Every time I try something else the compiler complains about incompatible types. I can't even copy the values to another array.

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
/*typedef struct tagRGBQUAD { 
  BYTE rgbBlue;
  BYTE rgbGreen;
  BYTE rgbRed;
  BYTE rgbReserved;
} RGBQUAD;*/

int main(int argc, char *argv[]) {
    // graps image from clipboard, if any
    HBITMAP b;
    RGBQUAD test[4];
    if(OpenClipboard(NULL) && IsClipboardFormatAvailable(CF_DIB)) {
        b = GetClipboardData(CF_DIB);
        CloseClipboard();
        //b[0]=37; // don't work
        //bt[0]=b[0]; // don't work
        //bt[0]=(int)b[0]; // don't work
        test[0]=b[13];
    }
    else
    printf("no sh!\n");
    //system("PAUSE");
    return 0;
}
Obviously the trouble all has to do with rgbquads/triplets, which I have no idea how to access directly or otherwise, thus, as the data is arranged as it would be if it was and int array, it's easy enough to print it. I've tried just about everything and unless you have some magic solution only thing left to do is to pull me together to read that link from pcmattman ;)

Re: Image manipulation in C

Posted: Tue Aug 24, 2010 2:13 am
by pcmattman
A HBITMAP is just a "handle to a bitmap". For all intents and purposes, it has no useful information for you to use (much like a HWND, or HDC). This is why functions like GetDIBits exist - to take a handle and do something useful with it.

Re: Image manipulation in C

Posted: Tue Aug 24, 2010 5:35 pm
by Zacariaz
I just wanted to let you all know that I've officially given up.

Should any of you stumble over a book, tutorial or similar, written for regular human beings, please let me know.


Best regards.

Re: Image manipulation in C

Posted: Tue Aug 24, 2010 10:04 pm
by Colonel Kernel
Is there some reason you need to do this in C using Win32? It would probably be way easier in C#/.NET.

Re: Image manipulation in C

Posted: Tue Aug 24, 2010 10:52 pm
by bewing
If you're willing to buy a book: Programming Windows, Charles Petzold. It actually explains how to do all this stuff. Including code.

Re: Image manipulation in C

Posted: Wed Aug 25, 2010 12:22 am
by MasterLee
Colonel Kernel wrote:Is there some reason you need to do this in C using Win32? It would probably be way easier in C#/.NET.
There is no need to stick on windows. In SDL 1.3 Clipboard support will be integrated.

Re: Image manipulation in C

Posted: Wed Aug 25, 2010 5:27 am
by Zacariaz
Colonel Kernel wrote:Is there some reason you need to do this in C using Win32? It would probably be way easier in C#/.NET.
The reason I want to do it in C is first of all part of a learning process. When it comes to why I want to get better at C specifically, it's because it seems like the best place to start since C is the basic for a lot of other programming languages, be it just the basic structure of it or be the language actually "build" on it, or inspired by it. It also give the programmer a lot of control, and I do like control.
bewing wrote:If you're willing to buy a book: Programming Windows, Charles Petzold. It actually explains how to do all this stuff. Including code.
I usually go to accu.org and read a review when I get a book suggestion, however, the book isn't listed, which worries me. I will of course look it up elsewhere before making any judgements.


Thanks.

Edit:
apparently new 5th and newest edition of "programming windows" is from 1998. I'd imagine that could course some serious problems. I've still to find a recent review.

Edit:
the FAQ on Petzold's website clearly state that newer versions of vista and/or windows 7 shouldn't be a problem, so I guess the only step left is to find a proper and recent review ;)