BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Reduce pixel Depth
Goto page 1, 2  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Graphics
View previous topic :: View next topic  
Author Message
Ronaldo Souza
Guest





PostPosted: Mon Aug 29, 2005 11:44 pm    Post subject: Re: Reduce pixel Depth Reply with quote



Charles,

Quote:
Note another poster pointed me to a previous posting, which mentioned
converting the Bitmap to GIF/JPG to reduce colour depth.
Yet this option is out, for I still NEED a bitmap.

Try the CreateOptimizedPaletteForSingleBitmap function from the unit
"PaletteLibrary" in the zip below. See the code for it's use.

http://www.efg2.com/Lab/Graphics/Colors/ShowDemoOne.ZIP

Good luck,
Ronaldo


Back to top
Charles Hacker
Guest





PostPosted: Mon Aug 29, 2005 11:45 pm    Post subject: Reduce pixel Depth Reply with quote



Hi all,

I am looking to reduce the color/pixel depth of a bitmap for copying.

The standard
BMap.PixelFormat:= pf16Bit;
Clipboard.Assign(Bmap);

Seems to copy the full 32bit color image of the display, (Thus the
bitmaps become massive in memory size).
(Even though the PixelFormat should have made it 16 bit).

So I am wondering how to decrease the pixel depth, so only a small
memory (pf16bit) image is copied to the clipbrd.

Note another poster pointed me to a previous posting, which mentioned
converting the Bitmap to GIF/JPG to reduce colour depth.
Yet this option is out, for I still NEED a bitmap.
Back to top
Charles Hacker
Guest





PostPosted: Tue Aug 30, 2005 12:18 am    Post subject: Re: Reduce pixel Depth Reply with quote



Ronaldo Souza wrote:
Quote:

Try the CreateOptimizedPaletteForSingleBitmap function from the unit
"PaletteLibrary" in the zip below. See the code for it's use.

http://www.efg2.com/Lab/Graphics/Colors/ShowDemoOne.ZIP

Yes I have certainly checked EFG's lab, and have seen this.

Although this determines an 'optimised' reduced colour bitmap pallete,
it STILL stores bitmaps in the full 24bit color depth.

Thus I am looking for something which will copy a reduced TBITMAP color
depth (pf16bit) to the clipboard.
(Not the default pf24bit, that it always seems to do).

--
Charles Hacker
Lecturer in Electronics and Computing
School of Engineering
Griffith University - Gold Coast
Australia

Back to top
Paul Nicholls
Guest





PostPosted: Tue Aug 30, 2005 1:35 am    Post subject: Re: Reduce pixel Depth Reply with quote

"Charles Hacker" <reply.to (AT) borland (DOT) newsgroups> wrote

Quote:
Ronaldo Souza wrote:

Try the CreateOptimizedPaletteForSingleBitmap function from the unit
"PaletteLibrary" in the zip below. See the code for it's use.

http://www.efg2.com/Lab/Graphics/Colors/ShowDemoOne.ZIP

Yes I have certainly checked EFG's lab, and have seen this.

Although this determines an 'optimised' reduced colour bitmap pallete,
it STILL stores bitmaps in the full 24bit color depth.

Thus I am looking for something which will copy a reduced TBITMAP color
depth (pf16bit) to the clipboard.
(Not the default pf24bit, that it always seems to do).


Not sure, but perhaps this page can help you :-)

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/dataexchange/clipboard/clipboardformats.asp

cheers,
Paul.



Back to top
Ronaldo Souza
Guest





PostPosted: Tue Aug 30, 2005 7:26 am    Post subject: Re: Reduce pixel Depth Reply with quote

Charles,

Try this:

//--------------------------------------------------------------------
uses
GIFImage,ClipBrd;

procedure TForm1.Button1Click(Sender: TObject);
var
BMP1,BMP2 : TBitmap;
MS1,MS2 : TMemoryStream;
DataPtr : Pointer;
DataHandle : THandle;
begin
BMP1 := TBitmap.Create;
try
BMP1.LoadFromFile('Test01.bmp');
if (BMP1.PixelFormat <> pf24Bit)
then BMP1.PixelFormat := pf24Bit;
BMP2 := ReduceColors(BMP1,rmQuantizeWindows,dmNearest,8,0);
try
// Convert BMP to DIB
MS1 := TMemoryStream.Create;
try
BMP2.SaveToStream(MS1);
MS1.Position:= SizeOf(TBitmapFileHeader);
MS2 := TMemoryStream.Create;
try
MS2.CopyFrom(MS1,MS1.Size-SizeOf(TBitmapFileHeader));
// Store DIB file in memory
Datahandle := GlobalAlloc(GMEM_MOVEABLE,MS2.Size);
DataPtr := GlobalLock(Datahandle);
Move(MS2.Memory^,DataPtr^,MS2.Size);
GlobalUnlock(Datahandle);
OpenClipboard(Application.Handle);
EmptyClipboard; //!!!!!!!!!!!!
SetClipboardData(CF_DIB,DataHandle);
CloseClipboard;
finally
MS2.Free;
end;
finally
MS1.Free;
end;
finally
BMP2.Free;
end;
finally
BMP1.Free;
end;
end;
//--------------------------------------------------------------------

HTH,
Ronaldo

Back to top
Ronaldo Souza
Guest





PostPosted: Tue Aug 30, 2005 7:37 am    Post subject: Re: Reduce pixel Depth Reply with quote

Charles,

Try this:
//-----------------------------------------------------------------
// Based on code by Bob Villiers
uses
GIFImage,ClipBrd;

procedure TForm1.Button1Click(Sender: TObject);
var
BMP1,BMP2 : TBitmap;
MS1,MS2 : TMemoryStream;
DataPtr : Pointer;
DataHandle : THandle;
begin
BMP1 := TBitmap.Create;
try
BMP1.LoadFromFile('Test01.bmp'); //!!!!!!!!!!!!
BMP2 := ReduceColors(BMP1,rmQuantizeWindows,dmNearest,8,0);
try
// Convert BMP to DIB
MS1 := TMemoryStream.Create;
try
BMP2.SaveToStream(MS1);
MS1.Position:= SizeOf(TBitmapFileHeader);
MS2 := TMemoryStream.Create;
try
MS2.CopyFrom(MS1,MS1.Size-SizeOf(TBitmapFileHeader));
// Store DIB file in memory
DataHandle := GlobalAlloc(GMEM_MOVEABLE,MS2.Size);
DataPtr := GlobalLock(DataHandle);
Move(MS2.Memory^,DataPtr^,MS2.Size);
GlobalUnlock(DataHandle);
OpenClipboard(Application.Handle);
EmptyClipboard; //!!!!!!!!!!!!
SetClipboardData(CF_DIB,DataHandle);
CloseClipboard;
finally
MS2.Free;
end;
finally
MS1.Free;
end;
finally
BMP2.Free;
end;
finally
BMP1.Free;
end;
end;
//-----------------------------------------------------------------


HTH,
Ronaldo

Back to top
Jens Gruschel
Guest





PostPosted: Tue Aug 30, 2005 8:48 am    Post subject: Re: Reduce pixel Depth Reply with quote

Quote:
MS1 := TMemoryStream.Create;
try
BMP2.SaveToStream(MS1);
MS1.Position:= SizeOf(TBitmapFileHeader);
MS2 := TMemoryStream.Create;
try
MS2.CopyFrom(MS1,MS1.Size-SizeOf(TBitmapFileHeader));
// Store DIB file in memory
DataHandle := GlobalAlloc(GMEM_MOVEABLE,MS2.Size);
DataPtr := GlobalLock(DataHandle);
Move(MS2.Memory^,DataPtr^,MS2.Size);

Tricky. But can't this be done with one memory stream only? Instead of
copying the data to a second memory stream, you could also use the first
memory stream for your move instruction (add the header offset to the
memory pointer).

Jens

--
Jens Gruschel
http://www.pegtop.net

Back to top
Ronaldo Souza
Guest





PostPosted: Tue Aug 30, 2005 9:35 am    Post subject: Re: Reduce pixel Depth Reply with quote

Jens Gruschel wrote:
Quote:
Tricky. But can't this be done with one memory stream only? Instead of
copying the data to a second memory stream, you could also use the first
memory stream for your move instruction (add the header offset to the
memory pointer).

Sure. Thanks!
Ronaldo

//---------------------------------------------------------------------
// Based on code by Bob Villiers
uses
GIFImage,ClipBrd;

procedure TForm1.Button2Click(Sender: TObject);
var
BMP1,BMP2 : TBitmap;
MS : TMemoryStream;
DataPtr : Pointer;
DataHandle : THandle;
szTBMPFHdr : integer;
begin
BMP1 := TBitmap.Create;
try
BMP1.LoadFromFile('Test01.bmp'); //!!!!!!!parm!

if (BMP1.PixelFormat > pf8bit)
then BMP2 := ReduceColors(BMP1,rmQuantizeWindows,dmNearest,8,0)
else begin
BMP2 := TBitmap.Create;
BMP2.Assign(BMP1);
end;
try
// Convert BMP to DIB
MS := TMemoryStream.Create;
try
BMP2.SaveToStream(MS);
szTBMPFHdr := SizeOf(TBitmapFileHeader);
MS.Position:= szTBMPFHdr;
// Store DIB file in memory
DataHandle := GlobalAlloc(GMEM_MOVEABLE,MS.Size-szTBMPFHdr);
DataPtr := GlobalLock(DataHandle);
Move(PByteArray(MS.Memory)^[szTBMPFHdr],DataPtr^,
MS.Size-szTBMPFHdr);
GlobalUnlock(DataHandle);
OpenClipboard(Application.Handle);
EmptyClipboard; //!!!!!!!parm!

SetClipboardData(CF_DIB,DataHandle);
CloseClipboard;
finally
MS.Free;
end;
finally
BMP2.Free;
end;
finally
BMP1.Free;
end;
end;
//---------------------------------------------------------------------


Back to top
Joris Van Damme
Guest





PostPosted: Tue Aug 30, 2005 5:08 pm    Post subject: Re: Reduce pixel Depth Reply with quote

Charles Hacker wrote:
Quote:
I am looking to reduce the color/pixel depth of a bitmap for copying.

The standard
BMap.PixelFormat:= pf16Bit;
Clipboard.Assign(Bmap);

Seems to copy the full 32bit color image of the display, (Thus the
bitmaps become massive in memory size).
(Even though the PixelFormat should have made it 16 bit).

The PixelFormat assigning does indeed decrease pixel depth (though not in a
very smart or visually pleasing way). However, what happens next, is that
the VCL dumps a DDB on the clipboard, old-style way that it inherits way
back from Win 3.1 Delphi 1. This way, what ends up on the clipboard, after a
needless as well as undesirable convertion, compares to pf32bit (but isn't
exactly that) if your display depth is 32bit, compares to pf24bit or pf16bit
(but isn't exactly that) if your display depth is 24 or 16 bit, or what ends
up on the clipboard is totally screwed on a system with an 8bit palette
display. In short, it's totally unreliable, and totally useless.

I'm might be a little out of date on how the most recent versions of Delphi
do it, but this is how it is done up to Delphi 6 at least, so I guess if
they haven't changed it by then it probably never will...

What you actually want, is to copy it as DIB. This is the correct and
recommended way ever since Win95, but not the way VCL works. You can thus
copy anything on there, from palette DIB to 32bit DIB, any way, independent
of particular system and display bitdepth. For this purpose, you'll need to
drop down to API level. Google on OpenClipboard and SetClipboardData and
such.

If you want to take it one step further, there's a most excellent mechanism
to force the system to simply make a note of the fact that you're able to
specify what is on the clipboard, without actually setting the clipboard
data right way. This avoids the operation and memory consumption if the
clipboard is never actually used by the user, and can also have great
advantages if the clipboard is actually used, depending on your overall
design. If you're interested in taking things to that level, google on
'delayed clipboard rendering'.

--
Joris Van Damme
[email]info (AT) awaresystems (DOT) be[/email]
http://www.awaresystems.be/
Download your free TIFF tag viewer for windows here:
http://www.awaresystems.be/imaging/tiff/astifftagviewer.html



Back to top
Joris Van Damme
Guest





PostPosted: Tue Aug 30, 2005 5:09 pm    Post subject: Re: Reduce pixel Depth Reply with quote

Ronaldo Souza wrote:
Quote:
BMP1.LoadFromFile('Test01.bmp'); //!!!!!!!!!!!!

That's copy 1.

Quote:
BMP2 := ReduceColors(BMP1,rmQuantizeWindows,dmNearest,8,0);

That's another copy, even if this second copy is reduced in color depth and
thus somewhat smaller, depending on whether ReduceColors actually works. (I
don't see it in the code you posted.)

Quote:
try
// Convert BMP to DIB
MS1 := TMemoryStream.Create;
try
BMP2.SaveToStream(MS1);

That's another copy, even if this third copy is not exactly a bitmap in the
DIB sense, it's still yet another memory block to allocate, copy to, etc.

Quote:
MS1.Position:= SizeOf(TBitmapFileHeader);
MS2 := TMemoryStream.Create;
try
MS2.CopyFrom(MS1,MS1.Size-SizeOf(TBitmapFileHeader));

That's another copy, fourth copy now!

Quote:
// Store DIB file in memory
DataHandle := GlobalAlloc(GMEM_MOVEABLE,MS2.Size);
DataPtr := GlobalLock(DataHandle);
Move(MS2.Memory^,DataPtr^,MS2.Size);

That's another copy, fifth copy now!

Quote:
GlobalUnlock(DataHandle);
OpenClipboard(Application.Handle);
EmptyClipboard; //!!!!!!!!!!!!
SetClipboardData(CF_DIB,DataHandle);
CloseClipboard;
finally
MS2.Free;
end;
finally
MS1.Free;
end;
finally
BMP2.Free;
end;
finally
BMP1.Free;
end;
end;

I hope the original bitmap was 'only' a few 100 K, or this is extremely bad.
Of course, if it was only a few 100 K, the original poster wouldn't have
objected to copying it to the clipboard without reducing color.

--
Joris Van Damme
[email]info (AT) awaresystems (DOT) be[/email]
http://www.awaresystems.be/
Download your free TIFF tag viewer for windows here:
http://www.awaresystems.be/imaging/tiff/astifftagviewer.html




Back to top
Ronaldo Souza
Guest





PostPosted: Tue Aug 30, 2005 10:38 pm    Post subject: Re: Reduce pixel Depth Reply with quote

Joris,

Thanks for the criticism but perhaps you didn't see my second post after
Jens pointed out I didn't need two MemoryStreams. Besides freeing up
BMP1 right after BMP2 is created, I don't see much to improve. Please
take a look. Any suggestions are welcome.

Quote:
That's another copy, even if this second copy is reduced in color depth and
thus somewhat smaller, depending on whether ReduceColors actually works. (I
don't see it in the code you posted.)

ReduceColors is from Anders Melander/Finn Tolderlund's TGIFImage
(mentioned in a previous post and in the uses clause) and my experience
with it has been great. 8 bits are usually more than enough for my
needs. As a test, I ran a few 1024x768x24 images with lots of unique
colors (239.532 up to 358.615) through this code:

ReduceColors(BMP1,rmQuantizeWindows,dmNearest,8,0);

The size went from 2.359.350 to 787.510 bytes (33% of original size)
*with _minimal_ loss of quality*.

Thanks,
Ronaldo


Back to top
Joris Van Damme
Guest





PostPosted: Wed Aug 31, 2005 1:18 am    Post subject: Re: Reduce pixel Depth Reply with quote

Ronaldo Souza wrote:
Quote:
Thanks for the criticism but perhaps you didn't see my second post
after Jens pointed out I didn't need two MemoryStreams. Besides
freeing up BMP1 right after BMP2 is created, I don't see much to
improve. Please take a look. Any suggestions are welcome.

It's easy to improve by not building on from buggy unreliable technology,
but sinking down to the (at least) equally simple API level. See my other
post. Any interface with something that requires you to make four redundant
copies of a bitmap to get this done, or three if you wish, should surely be
considered not an option at all. The Win API level is good, does not require
these redundant copies, allows you to actually copy a DIB in any bitdepth
you like, the recommended way, and is extremely easy to use.

Quote:
ReduceColors is from Anders Melander/Finn Tolderlund's TGIFImage
(mentioned in a previous post and in the uses clause) and my
experience with it has been great.

OK.


--
Joris Van Damme
[email]info (AT) awaresystems (DOT) be[/email]
http://www.awaresystems.be/
Download your free TIFF tag viewer for windows here:
http://www.awaresystems.be/imaging/tiff/astifftagviewer.html



Back to top
Charles Hacker
Guest





PostPosted: Wed Aug 31, 2005 1:25 am    Post subject: Re: Reduce pixel Depth Reply with quote

Ronaldo Souza wrote:
Quote:

Charles,

Try this:
code snipped

Thanks, have not tried the code yet, but that should do.
Note even the 'inefficent code' you gave would work for my purposes.

I actually want to use it for my Electonic Circuit Schematic Drawing
Application.
This app produces two color (black and white) diagrams.
When I generate a bitmap from the display (and make the bitmap pf2bit or
pf8bit), and save it, the bitmap is quite small (~100 kb).
Yet when I copy that same bitmap to clipboard, it always becomes a
16Millon color bitmap, of Megabyte size (~1,000 kb).

So I usually had to paste the large (Megabyte) bitmap to Paintshop,
reduce the colors down in Paintshop, copy that image back to clipoboard,
which then was a resonable (~100kb) size, for imbedding into other apps.


--
Charles Hacker
Lecturer in Electronics and Computing
School of Engineering
Griffith University - Gold Coast
Australia

Back to top
Charles Hacker
Guest





PostPosted: Wed Aug 31, 2005 1:31 am    Post subject: Re: Reduce pixel Depth Reply with quote

Joris Van Damme wrote:
Quote:

The Win API level is good, does not require
these redundant copies, allows you to actually copy a DIB in any bitdepth
you like, the recommended way, and is extremely easy to use.

Okay, so do you have example code for this?


--
Charles Hacker
Lecturer in Electronics and Computing
School of Engineering
Griffith University - Gold Coast
Australia

Back to top
Ronaldo Souza
Guest





PostPosted: Wed Aug 31, 2005 1:38 am    Post subject: Re: Reduce pixel Depth Reply with quote

Joris Van Damme wrote:

Sorry to insist but I'm really confused now... :-(

Quote:
It's easy to improve by not building on from buggy unreliable technology,
but sinking down to the (at least) equally simple API level.

What do you mean by "API Level"? The functions you mention in your post
"OpenClipboard, SetClipboardData and such." are exactly what I'm using
(or at least *trying* to learn how to use... Smile)


Quote:
Any interface with something that requires you to make four redundant
copies of a bitmap to get this done, or three if you wish, should
surely be considered not an option at all.

The way I understood it, I need one copy to read the original bitmap;
another for the color reduced bitmap; the memory stream to get a memory
image of the reduced bitmap file and a global memory block to pass to
SetClipboardData. The stream could be avoided if there is a way to get
the info I'm reading from the it (after skipping the header) from a
TBitmap structure. Is this possible?


Quote:
The Win API level is good, does not require these redundant copies,
allows you to actually copy a DIB in any bitdepth you like, the
recommended way, and is extremely easy to use.

Can you give me some pointers to these functions? A little demo would be
even nicer... :-;

Thanks,
Ronaldo


Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Graphics All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.