|
-
Nov 6th, 2002, 12:00 PM
#1
Thread Starter
Member
Bitmap in hMemDC [RESOLVED]
Bitmap in hMemDC
Hello again everyone, 
I have the following situation and am wondering if any of you clever people would be able to help me resolve it (I know CornedBee has been very helpful in the past).
I have managed to place a bitmap within a hMemDC, only I would like to convert this bitmap to a much smaller image format without saving it so maybe placing it into another hMemdc. From reading various threads on this forum I know that it is fairly difficult to convert it to a JPEG without using a .dll which I do not mind (as long as they are free) using but most of these appear to require the image to be saved to disk rather than simply placing it into another hMemDC. I am also not really bothered as to what image type I convert it to as long as the size of the image is at least halved (not the actual dimensions of the picture).
I would appreciate any help in this matter, as it is now driving me mad!
Thanks in advance,
Last edited by ISquishWorms; Nov 9th, 2002 at 07:29 AM.
ISquishWorms
-
Nov 6th, 2002, 02:53 PM
#2
Monday Morning Lunatic
But then it wouldn't be a memory DC. When you store them in memory, they *must* be uncompressed and in full display format.
Size is only really relevant when you save it anyway. I can't see why you want to do this here.
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Nov 6th, 2002, 03:10 PM
#3
Thread Starter
Member
Hi Parksie,
Thanks for your quick reply. Maybe I should have said that I have an HBITMAP stored in memory, and I wish to convert this into a alternative smaller format within memory rather than having to save it. I know this is possible as I have managed this in Delphi, but now wish to do this in C as I prefer it to Delphi.
Thanks,
ISquishWorms
-
Nov 6th, 2002, 03:12 PM
#4
Monday Morning Lunatic
I wouldn't recommend it. JPEG decoding is not fast enough for real-time display onscreen, so you'd end up trading memory for CPU time.
Why is it so important?
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Nov 6th, 2002, 03:20 PM
#5
Thread Starter
Member
Parksie talk about quick, how quick was that reply I was only editing my responce to your first reply to find that your had already replied my second .
It does not have to be in JPEG format (just a format with a fairly good compression ratio) and I am not trying to decode it I would like to encode it into an alternative format within memory. There must be a dll (free preferably) out there that will allow me to do this I really don't want to have to use Delphi for a solution but guess if I have to then so be it.
-
Nov 6th, 2002, 03:26 PM
#6
Monday Morning Lunatic
If I'm here I'm usually fairly fast 
So you just want to store a compressed version in memory somewhere, that can me decompressed in non-real-time once you need it real-time, right?
You need to be *very* careful because with lossy compression you'll cause lots of problems with the two pictures becoming inconsistent, and progressing to severe data loss.
You could try using zlib, that could help, although you wouldn't get the compression rates of JPEG, it solves the loss problem.
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Nov 6th, 2002, 04:09 PM
#7
Thread Starter
Member
Parksie, I am going to start calling your the bullet as your so fast to reply.
Yes that is exactly what I would like to achieve, would this zlib allow me to hold my image in memory. Sorry but I am not familiar with zlib do you have an examples or info? Is this a picture format or simply a compression routine? Typically what compression ratios will this allow me to achive?
Thanks for all your help on this matter so far and of course your speedy replies.
-
Nov 6th, 2002, 04:32 PM
#8
Monday Morning Lunatic
ZLib is merely a compression format, the same as used in ZIP files, GZip, PDF, TIFF, etc. 
Look on google for the latest location of the website 
It uses a sliding-window algorithm, and normally gets much better results on text (you can get them down to about 5 to 10 percent size) than continuous-tone images such as photos (perhaps about 70% or so). Cartoon style images can get about 50% or so.
What type of images are they? You might do better with some kind of RLE method. Dunno, don't have a copy of Windows to test this on
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Nov 6th, 2002, 05:19 PM
#9
Thread Starter
Member
Parksie,
You don't have a copy of Windows? I take it that you do your programming on a different OS like Linux then (maybe).
They are just fairly large 24bit bitmaps, some of the ones that I will be working with are currently 2meg in size. Thanks for the info on zlib I am off to try and find their website to ascertain what is required and what can be achieved using this method.
In the meantime what is this RLE method that you mentioned sounds interesting? Do your have any examples or know where I might find some?
Thanks once again for the replies and the time your taking in trying to help me find a solution.
-
Nov 6th, 2002, 05:29 PM
#10
Monday Morning Lunatic
Last year I was doing it professionally on multiprocessor SGI systems running Irix (Unix variant), and decided I preferred it, so I made the move to GNU/Linux on my personal machine. Already had it on my router (uptime since last power cut below ) so I knew a little bit about it.
Aaaaanyway.
RLE == Run Length Encoding. Only works well for cartoon style images with large blocks of the same colour, because rather than going, "red red red red green green purple blue blue blue blue blue blue blue" you can go "4 red 2 green purple 7 blue".
Almost unusable for photographic or otherwise continuous-tone images though.
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Nov 6th, 2002, 05:52 PM
#11
Thread Starter
Member
The pictures that I am dealing with are not cartoons so I guess that I should forget the RLE method for this purpose then, although it is possible that some of them (not all) may have fairly large colour blocks that are the same. Considering that not all of the pictures will possibly have these large blocks of colour I guess I should go with the average picture type and try and use an alternative method of compressing them for now (does this sound reasonable?). Would the RLE method work better than the zlib method when the pictures have large colour blocks or would zlib do just as good a job?
I have been to the zlib website and downloaded the source, although have not yet looked at it. I take it I will need to compile the source myself? Are there any good examples of using zlib?
Thanks, Parksie I don’t think I have ever had my forum threads replied too as quickly as you have this one.
-
Nov 7th, 2002, 02:42 PM
#12
Was not around for a while...
RLE will do better when there are large blocks of the same color (actually they don't need to be blocks, horizontal lines are just as good because of the way RLE works). It can also be decompressed nearly in real-time (depends on CPU and memory speed, mainly memory).
But since you probably don't know what to expect I recommend zlib.
But you should ask yourself: is 30% memory saving worth the loss of speed? If you tell us what you want to do exactly, we might help you with that decision.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Nov 7th, 2002, 04:01 PM
#13
Thread Starter
Member
Hi CornedBee, it's nice to see your back. I did notice that you had not been around as much as usual, been anywhere nice? I was getting a little worried as I normally count on you to provide me with reasonable answers to my questions. 
I think I may give this RLE method a go if only to learn from it as it sounds interesting especially as both you and Parksie (who I consider to be both experts when it comes to C++) mentioned it. Do you have any good examples or know where I might find some that will get me started?
I have not decided against using zlib it's just that I would like to experiment using RLE as it is a new concept to me. I may afterwards revert back to trying to use zlib.
Thanks for the reply and advice CornedBee,
-
Nov 8th, 2002, 07:47 AM
#14
RLE is a very old technique, but the implementation always varies a little. Maybe you know the pcx bitmap format, it uses RLE. I think it might be a good format to use. You can get information on it on wotsit.org.
I have thought of an RLE format to use for pure black/white images (RLE really rocks there). It goes like this: every pixel is two bits. The first is the pixel value, the second is 0 if it's a single pixel or 1 if it's repeated. If it is, the next n bits are the repeat count (not necessarily byte-aligned, and I have to think of a good value for n, must be divisible by 2).
Of course this only works for black/white images.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Nov 8th, 2002, 08:14 AM
#15
Thread Starter
Member
CornedBee, thanks for the insight I never knew that the pcx format used RLE, mind you I did not know about RLE until recently. I will check out that website that you mentioned and have a look.
My first hurdle in trying to implement this method is that I need to know how to access the individual bytes of the HBITMAP that I store in memory and I am unsure how to do this. I did some of my own investigation into the RLE method as well last night and found the following code (it is not my code), does this code look like a good starting point for what I am trying to achieve? Are there any obvious mistakes in the code (I could not spot any, but as you have vastly more experience in C++ you may)? Your black and white method sounds interesting too, although my pictures are currently in colour I was considering maybe converting them to greyscale, but again I am a little unsure on how I would do this.
RLE Compression / Decompression, by William Swanson:
Code:
/******************************************************************************
* LoadRLE / SaveRLE - Load and save binary data using RLE compression.
* Run-length tokens have a set MSB, while data tokens have a cleared
* MSB. The value of the token's remaining bits plus one indicates the
* length of the block. The minimum run length is three bytes, while
* the maximum is 128.
*
* data - Array holding data to load or save.
* size - Size of the data array.
* file - The file pointer to use.
* return - Total number of bytes read from or written to data[].
*/
size_t LoadRLE (unsigned char data[], size_t size, FILE *file)
{
unsigned char token;
unsigned int length;
size_t total = 0;
while(size && fread(&token, 1, 1, file))
{
length = (token & ~0x80) + 1;
if (length > size)
{
return total;
}
if(token & 0x80)
{
if(!fread(&token, 1, 1, file))
{
return total;
}
memset(data, token, length);
}
else
{
if(fread(data, 1, length, file) != length)
{
return total;
}
}
data += length, size -= length, total += length;
}
return total;
}
/*************************************/
size_t SaveRLE (unsigned char data[], size_t size, FILE *file)
{
unsigned char token;
unsigned int i;
size_t total = 0;
while(size)
{
/*This loop identifies blocks of repeating data:*/
i = 2;
while(i < size && i < 128 &&
data[i] == data[i - 1] && data[i - 1] == data[i - 2])
i++;
/*If repeating data was found, save it:*/
if(i > 2)
{
token = i - 1 | 0x80;
if(!fwrite(&token, 1, 1, file))
return total;
if(!fwrite(data, 1, 1, file))
return total;
data += i, size -= i, total += i;
}
/*This loop identifies blocks of non-repeating data:*/
i = 0;
while(i < size && i < 128 && (i + 2 > size ? 1 :
data[i] != data[i + 1] || data[i + 1] != data[i + 2]))
i++;
/*If non-repeating data was found, save it:*/
if(i){
token = i - 1;
if(!fwrite(&token, 1, 1, file))
return total;
if(fwrite(data, 1, i, file) != i)
return total;
data += i, size -= i, total += i;
}
}
return total;
}
Any advice CornedBee will as always be gratefully appreciated, thanks in advance.
Last edited by ISquishWorms; Nov 8th, 2002 at 08:20 AM.
ISquishWorms
-
Nov 8th, 2002, 08:35 AM
#16
Looks ok, but I'm not looking at it in great detail.
Beware if you want to change the pixel values of a HBITMAP, you'll get weird effects and probably no memory savings.
It's better to save the pixel data in your own memory location and create a HBITMAP every time you need it, then decompress into it, blit to the screen and destroy the bitmap.
greyscale conversion goes like this:
byte r = redvalueofpixel(pixel);
byte g = greenvalueofpixel(pixel);
byte b = bluevalueofpixel(pixel);
float gray = 0.3333f * r + 0.5f * g + 0.1111f * b;
r = g = b = (byte)gray;
setpixelrgb(pixel, r, g, b);
Do this for every pixel. The numbers are scaling factors, because the human eye doesn't weigh all colors the same.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Nov 8th, 2002, 08:36 AM
#17
On an unrelated question: which is American English and which is Bristish English:
grey
gray
?
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Nov 8th, 2002, 09:07 AM
#18
Thread Starter
Member
Both are valid in UK English but mean something different.
UK English Definitions:
Grey: intermediate between black and white, coloured like ashes or lead.
Gray: (Phys.) unit of absorbed radiation dose, corresp. to one joule per kilogram.
I am from the uk by the way.
-
Nov 8th, 2002, 09:30 AM
#19
Thread Starter
Member
Beware if you want to change the pixel values of a HBITMAP, you'll get weird effects and probably no memory savings. It's better to save the pixel data in your own memory location and create a HBITMAP every time you need it, then decompress into it, blit to the screen and destroy the bitmap.
I am not sure I understand what you are saying. I currently have my HBITMAP in memory and wish to compress it using a compression routine, but I am a little confused now on how to do this. Do I need to address each pixel and compress it or convert each pixel into a byte? Why would I get strange effects? I thought I had started to understand what it is I need to do but now I am unsure again ahhhh.
Thanks for any further explanation(s) that you maybe able to provide to help me understand exactly what process and approach I need to take with this.
-
Nov 8th, 2002, 09:33 AM
#20
You can get access to the pixel data using GetObject.
But when you compress the data and then do
SelectObject(hdc, hbmCompressed);
the result won't be what you expect.
So I'd rather have a BYTE array with the compressed data and uncompress it every time you draw, then remove the uncompressed copy.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Nov 8th, 2002, 01:43 PM
#21
Thread Starter
Member
OK thanks, I think I understand now but that does mean that potentially the array could be quite large. Is there a limit on how big an array can be? How would I declare such a large array? I have also been investigating the Huffman’s method of compression which do you think might give me the best results. Is the Huffman compression better than RLE?
Sorry to keep bothering you with all these questions.
Thanks again for the time your taking to help me!!
-
Nov 8th, 2002, 08:00 PM
#22
Don't know what Huffman's compression is. Isn't it the compression algorithm underlying JPEG? If so, it's lossy.
If windows can internally store an array large enough to hold a complete bitmap then why shouldn't you?
Don't declare it on the stack, use new, malloc, HeapAlloc or (best for really large arrays) VirtualAlloc.
For stack arrays the size limit is very low: the whole stack can only be 1 MB large, so a 500k array is very dangerous.
Heap arrays I think are bound to the page size, but I might be wrong. Arrays allocated with VirtualAlloc are only bound by available memory, both physical and virtual.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Nov 8th, 2002, 09:59 PM
#23
Thread Starter
Member
-
Nov 9th, 2002, 06:03 AM
#24
Monday Morning Lunatic
Huffman coding is partially used in ZIP compression, so it's not lossy. It is also used in JPEG, I think (it's a very versatile technique using trees).
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Nov 9th, 2002, 07:07 AM
#25
The simplest usage of VirtualAlloc is
LPVOID lpMem = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
size should be a multiple of the system page size for maximum efficiency (it's actually automatically rounded up) which can be obtained with GetSystemInfo, where it is the dwPageSize member of the SYSTEM_INFO structure.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Nov 9th, 2002, 07:29 AM
#26
Thread Starter
Member
OK thanks, you both have been extremely helpful!
I will mark this thread as resolved now as it is time that I actually go and try and put some of what I have learnt in to practice and I have taken too much of your time already. I may be back to ask more questions if things don’t seem to be working out too well, if that is ok. So I guess here comes the tricky part actually programming the routines. 
Cya for now
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|