473,472 Members | 2,257 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Bitmap.Clone

The following code throws a out of memory exception, I have another function
that does the same thing using the bitmap lock but its way slow. Anyone
know how to fix this one?

public static Bitmap GetClonedBitmap(int width, int height, string str, Font
font, StringAlignment Alignment)
{
Rectangle r = new Rectangle(1, 1, width-1, height-1);
using (Bitmap tmpBmp = new Bitmap(width, height))
{
using (Graphics g = Graphics.FromImage(tmpBmp))
{
g.FillRectangle(Brushes.White, r);
using (StringFormat sf = new
StringFormat(StringFormat.GenericDefault))
{
sf.Alignment = Alignment;
sf.Trimming = StringTrimming.None;
sf.LineAlignment = StringAlignment.Center;
sf.FormatFlags = StringFormatFlags.NoWrap;
g.DrawString(str, font, Brushes.Black, r, sf);

return tmpBmp.Clone(r, PixelFormat.Format1bppIndexed);
}
}
}
}

Regards,
John
May 10 '06 #1
4 10490
You can't change the bitmap pixel format like that. That's where the error
is coming from.

If you want to convert an arbitrary bitmap to 1bpp indexed see the GDI+ FAQ.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

"John J. Hughes II" <no@invalid.com> wrote in message
news:u9**************@TK2MSFTNGP03.phx.gbl...
The following code throws a out of memory exception, I have another
function that does the same thing using the bitmap lock but its way slow.
Anyone know how to fix this one?

public static Bitmap GetClonedBitmap(int width, int height, string str,
Font font, StringAlignment Alignment)
{
Rectangle r = new Rectangle(1, 1, width-1, height-1);
using (Bitmap tmpBmp = new Bitmap(width, height))
{
using (Graphics g = Graphics.FromImage(tmpBmp))
{
g.FillRectangle(Brushes.White, r);
using (StringFormat sf = new
StringFormat(StringFormat.GenericDefault))
{
sf.Alignment = Alignment;
sf.Trimming = StringTrimming.None;
sf.LineAlignment = StringAlignment.Center;
sf.FormatFlags = StringFormatFlags.NoWrap;
g.DrawString(str, font, Brushes.Black, r, sf);

return tmpBmp.Clone(r, PixelFormat.Format1bppIndexed);
}
}
}
}

Regards,
John

May 10 '06 #2
Thanks for the comments. Yes I am currently doing something similar to the
code on your website but it way to slow. I have to convert 28 128/16
bitmaps and it takes too long on my computer so I know my customers are
going to scream. I'm pretty sure it was faster in .NET 1.1 then 2 but it
what we have now so I was looking for a faster method.

It seemed based on the direction for the Bitmap.Clone function it would
change the pixel format, must have misunderstood.

From BOL:
"Bitmap.Clone (RectangleF, PixelFormat)
Creates a copy of the section of this Bitmap defined with a specified
PixelFormat enumeration."

"Bob Powell [MVP]" <bob@_spamkiller_.bobpowell.net> wrote in message
news:%2******************@TK2MSFTNGP05.phx.gbl...
You can't change the bitmap pixel format like that. That's where the error
is coming from.

If you want to convert an arbitrary bitmap to 1bpp indexed see the GDI+
FAQ.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

"John J. Hughes II" <no@invalid.com> wrote in message
news:u9**************@TK2MSFTNGP03.phx.gbl...
The following code throws a out of memory exception, I have another
function that does the same thing using the bitmap lock but its way slow.
Anyone know how to fix this one?

public static Bitmap GetClonedBitmap(int width, int height, string str,
Font font, StringAlignment Alignment)
{
Rectangle r = new Rectangle(1, 1, width-1, height-1);
using (Bitmap tmpBmp = new Bitmap(width, height))
{
using (Graphics g = Graphics.FromImage(tmpBmp))
{
g.FillRectangle(Brushes.White, r);
using (StringFormat sf = new
StringFormat(StringFormat.GenericDefault))
{
sf.Alignment = Alignment;
sf.Trimming = StringTrimming.None;
sf.LineAlignment = StringAlignment.Center;
sf.FormatFlags = StringFormatFlags.NoWrap;
g.DrawString(str, font, Brushes.Black, r, sf);

return tmpBmp.Clone(r, PixelFormat.Format1bppIndexed);
}
}
}
}

Regards,
John


May 10 '06 #3
"Bob Powell [MVP]" <bob@_spamkiller_.bobpowell.net> wrote:
If you want to convert an arbitrary bitmap to 1bpp indexed see the GDI+ FAQ.


The GDI+ FAQ says to iterate "for y=0 to height, for x=0 to width"
which is terribly slow. This is a shame, because Windows already
contains built-in functionality to convert from arbitrary pixelformat
into 1bpp pixelformat. And it's fast -- my laptop takes just 50ms to
convert a 1024x768 bitmap into monochrome, or just 5ms to convert a
200x200 bitmap.

Here's the code for it. I've written it in C++ using native win32
calls. Hopefully someone can turn it into C#. (I had trouble turning
it into C#, because I couldn't find how to construct a Bitmap() object
from an existing HBITMAP, and I couldn't find how to BitBlt/DrawImage
onto an existing 1bpp Bitmap object.)

HBITMAP CreateMonochromeCopy(HBITMAP hbm_src)
{
// retrieve the size of the original bitmap
DIBSECTION dibs; GetObject(hbm_src,sizeof(dibs),&dibs);
int width=dibs.dsBm.bmWidth, height=dibs.dsBm.bmHeight;
//
// create a new bitmap of the same dimensions with a 1bpp monchrome
palette
typedef struct {BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[2];}
MONOBITMAPINFO;
MONOBITMAPINFO bmi; ZeroMemory(&bmi,sizeof(bmi));
bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth=width;
bmi.bmiHeader.biHeight=height;
bmi.bmiHeader.biPlanes=1;
bmi.bmiHeader.biBitCount=1;
bmi.bmiHeader.biCompression=BI_RGB;
bmi.bmiHeader.biSizeImage=((width+7)&0xFFFFFFF8)*h eight/8;
bmi.bmiHeader.biXPelsPerMeter=1000000;
bmi.bmiHeader.biYPelsPerMeter=1000000;
bmi.bmiHeader.biClrUsed=2;
bmi.bmiHeader.biClrImportant=2;
bmi.bmiColors[0].rgbRed=0; bmi.bmiColors[0].rgbGreen=0;
bmi.bmiColors[0].rgbBlue=0; bmi.bmiColors[0].rgbReserved=0;

bmi.bmiColors[1].rgbRed=255;bmi.bmiColors[1].rgbGreen=255;bmi.bmiColors[1].rgbBlue=255;bmi.bmiColors[1].rgbReserved=0;
void *bits; HBITMAP hbm_dst =
CreateDIBSection(0,(BITMAPINFO*)&bmi,DIB_RGB_COLOR S,&bits,0,0);
//
// BitBlt the original image into the new one. Windows and the
// graphics accelerator will take care of color thresholds &c.
HDC sdc = GetDC(0);
HDC hdc_src = CreateCompatibleDC(sdc);
HDC hdc_dst = CreateCompatibleDC(sdc);
SelectObject(hdc_src,hbm_src);
SelectObject(hdc_dst,hbm_dst);
BitBlt(hdc_dst,0,0,width,height,hdc_src,0,0,SRCCOP Y);
DeleteDC(hdc_src);
DeleteDC(hdc_dst);
ReleaseDC(0,sdc);
//
return hbm_dst;
}

Here's a complete program to watch it in action:

#include <windows.h>

int main()
{ HDC sdc = GetDC(0);
HBITMAP hbm = CreateCompatibleBitmap(sdc,1024,768);
HDC hdc = CreateCompatibleDC(sdc);
SelectObject(hdc,hbm);
RECT rc; rc.left=0; rc.top=0; rc.right=1024; rc.bottom=768;
FillRect(hdc,&rc,(HBRUSH)GetStockObject(WHITE_BRUS H));
SetTextColor(hdc,RGB(255,0,0));
TextOut(hdc,10,10,L"Hello World",11);
DeleteDC(hdc);
//
HBITMAP hbmi[100];
unsigned int time1=GetTickCount();
for (int i=0; i<100; i++) hbmi[i] = CreateMonochromeCopy(hbm);
unsigned int time2=GetTickCount();
unsigned int diff = time2-time1;
//
hdc = CreateCompatibleDC(sdc);
SelectObject(hdc,hbmi[0]);
BitBlt(sdc,0,0,200,200,hdc,0,0,SRCCOPY);
DeleteDC(hdc);
ReleaseDC(0,sdc);
DeleteObject(hbm);
for (int i=0; i<100; i++) DeleteObject(hbmi[i]);
Sleep(2000);
return 0;
}
--
Lucian
May 10 '06 #4
Thanks, will look into it.

"Lucian Wischik" <lu***@wischik.com> wrote in message
news:jg********************************@4ax.com...
"Bob Powell [MVP]" <bob@_spamkiller_.bobpowell.net> wrote:
If you want to convert an arbitrary bitmap to 1bpp indexed see the GDI+
FAQ.


The GDI+ FAQ says to iterate "for y=0 to height, for x=0 to width"
which is terribly slow. This is a shame, because Windows already
contains built-in functionality to convert from arbitrary pixelformat
into 1bpp pixelformat. And it's fast -- my laptop takes just 50ms to
convert a 1024x768 bitmap into monochrome, or just 5ms to convert a
200x200 bitmap.

Here's the code for it. I've written it in C++ using native win32
calls. Hopefully someone can turn it into C#. (I had trouble turning
it into C#, because I couldn't find how to construct a Bitmap() object
from an existing HBITMAP, and I couldn't find how to BitBlt/DrawImage
onto an existing 1bpp Bitmap object.)

HBITMAP CreateMonochromeCopy(HBITMAP hbm_src)
{
// retrieve the size of the original bitmap
DIBSECTION dibs; GetObject(hbm_src,sizeof(dibs),&dibs);
int width=dibs.dsBm.bmWidth, height=dibs.dsBm.bmHeight;
//
// create a new bitmap of the same dimensions with a 1bpp monchrome
palette
typedef struct {BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[2];}
MONOBITMAPINFO;
MONOBITMAPINFO bmi; ZeroMemory(&bmi,sizeof(bmi));
bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth=width;
bmi.bmiHeader.biHeight=height;
bmi.bmiHeader.biPlanes=1;
bmi.bmiHeader.biBitCount=1;
bmi.bmiHeader.biCompression=BI_RGB;
bmi.bmiHeader.biSizeImage=((width+7)&0xFFFFFFF8)*h eight/8;
bmi.bmiHeader.biXPelsPerMeter=1000000;
bmi.bmiHeader.biYPelsPerMeter=1000000;
bmi.bmiHeader.biClrUsed=2;
bmi.bmiHeader.biClrImportant=2;
bmi.bmiColors[0].rgbRed=0; bmi.bmiColors[0].rgbGreen=0;
bmi.bmiColors[0].rgbBlue=0; bmi.bmiColors[0].rgbReserved=0;

bmi.bmiColors[1].rgbRed=255;bmi.bmiColors[1].rgbGreen=255;bmi.bmiColors[1].rgbBlue=255;bmi.bmiColors[1].rgbReserved=0;
void *bits; HBITMAP hbm_dst =
CreateDIBSection(0,(BITMAPINFO*)&bmi,DIB_RGB_COLOR S,&bits,0,0);
//
// BitBlt the original image into the new one. Windows and the
// graphics accelerator will take care of color thresholds &c.
HDC sdc = GetDC(0);
HDC hdc_src = CreateCompatibleDC(sdc);
HDC hdc_dst = CreateCompatibleDC(sdc);
SelectObject(hdc_src,hbm_src);
SelectObject(hdc_dst,hbm_dst);
BitBlt(hdc_dst,0,0,width,height,hdc_src,0,0,SRCCOP Y);
DeleteDC(hdc_src);
DeleteDC(hdc_dst);
ReleaseDC(0,sdc);
//
return hbm_dst;
}

Here's a complete program to watch it in action:

#include <windows.h>

int main()
{ HDC sdc = GetDC(0);
HBITMAP hbm = CreateCompatibleBitmap(sdc,1024,768);
HDC hdc = CreateCompatibleDC(sdc);
SelectObject(hdc,hbm);
RECT rc; rc.left=0; rc.top=0; rc.right=1024; rc.bottom=768;
FillRect(hdc,&rc,(HBRUSH)GetStockObject(WHITE_BRUS H));
SetTextColor(hdc,RGB(255,0,0));
TextOut(hdc,10,10,L"Hello World",11);
DeleteDC(hdc);
//
HBITMAP hbmi[100];
unsigned int time1=GetTickCount();
for (int i=0; i<100; i++) hbmi[i] = CreateMonochromeCopy(hbm);
unsigned int time2=GetTickCount();
unsigned int diff = time2-time1;
//
hdc = CreateCompatibleDC(sdc);
SelectObject(hdc,hbmi[0]);
BitBlt(sdc,0,0,200,200,hdc,0,0,SRCCOPY);
DeleteDC(hdc);
ReleaseDC(0,sdc);
DeleteObject(hbm);
for (int i=0; i<100; i++) DeleteObject(hbmi[i]);
Sleep(2000);
return 0;
}
--
Lucian

May 11 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: ekey | last post by:
Hi: I want to create Bmp by fellow code,and it good work, Bitmap bitmap1 = new Bitmap((Image)iData.GetData(DataFormats.Bitmap)) but i want to cut the part of the Bmp now . How to do it ? ...
1
by: André Borchert | last post by:
Hello, how do you select a region (area = x1,y1,x2,y2) of a bitmap and cut or copy this selection into a new bitmap ? The original could be a Bitmap object or a Image/PictureBox object....
0
by: James Dean | last post by:
Question 1:I have my full image and i only display that when the zoom rate is 1:1......i guess i will set my default display to 1:16.....is it okay to just return a thumbnail of the entire image...
3
by: RicercatoreSbadato | last post by:
=========== INTRODUCTION: =========== I'd like to take only a part of a Bitmap. I'm workin in unsafe mode with the pointers: unsafe { byte * p_init = (byte *)(void *)Scan0; byte * p_I =...
1
by: RicercatoreSbadato | last post by:
Help plz, what's happen exactly when I do Bitmap.Clone() ?
2
by: active | last post by:
I find Bitmap.Save works for WMF files but Bitmap.FromFile does not. If I use FromFile on a WMF file that came with VS I get an exception. If I use it on a WMF file created with Bitmap.Save I...
2
by: Mad Scientist Jr | last post by:
I have a bitmap (32 pixels high, 8192 pixels wide) that contains 255 images, each 32 pixels wide, that I would like to chop up into individual 32x32 bitmap files. Rather than spending hours in...
2
by: John | last post by:
The following 4 lines add a border to a bitmap and save it into clipboard, however it also add a border to the bitmap on the screen. I want to create a temp copy of the bitmap and add a border to...
1
by: TG01 | last post by:
I cannot clone a bitmap.. the error on the offending line says: Cannot implicitly convert type 'object' to 'System.Drawing.Bitmap'. An explicit conversion exists (are you missing a cast?) ...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.