So I've heard that GDI supports hardware acceleration. I have this code here:
var x = 1;
if (solidBrush == IntPtr.Zero)
{
solidBrush = CreateSolidBrush(ColorTranslator.ToWin32(Color.FromArgb(120, 120, 120)));
hDC = CreateGraphics().GetHdc();
}
index += x;
int w = x;
int h = Height;
//create memory device context
var memdc = CreateCompatibleDC(hDC);
//create bitmap
var hbitmap = CreateCompatibleBitmap(hDC, index, h);
////select bitmap in to memory device context
var holdbmp = SelectObject(memdc, hbitmap);
RECT rect = new RECT(new Rectangle(0, 0, w, h));
FillRect(memdc, ref rect, solidBrush);
AlphaBlend(hDC, index - x, 0, w, h, memdc, 0, 0, w, h, new BLENDFUNCTION(0, 0, 128, 0));
SelectObject(memdc, holdbmp);
DeleteObject(hbitmap);
DeleteDC(memdc);
which uses GDI to draw an animation (a box), but I see no GPU usage. Is it that GDI just doesn't support HW acceleration?
Thanks.
Related
private void FindPoints()
{
GraphicsPath gp = new GraphicsPath();
int x, y, p, j, wdthHght;
int bytes;
byte[] rgbValuesWithClouds;
byte[] rgbValuesWithoutClouds;
IntPtr ptr;
Rectangle rect;
BitmapData bitmap_Data;
Bitmap bmpWithClouds; //No memory is allocated
Bitmap bmpWithoutClouds; //No memory is allocated
gp.AddEllipse(new RectangleF(73, 72, 367, 367));
//using the using statement, bmpWithClouds bitmap is automatically disposed at the end of statement. No memory leaks :)
using (bmpWithClouds = new Bitmap(mymem))
{
rect = new Rectangle(0, 0, bmpWithClouds.Width, bmpWithClouds.Height);
wdthHght = bmpWithClouds.Width;
//Lock bitmap to copy its color information fast
bitmap_Data = bmpWithClouds.LockBits(rect, ImageLockMode.ReadWrite, bmpWithClouds.PixelFormat);
ptr = bitmap_Data.Scan0;
bytes = bitmap_Data.Stride * bmpWithClouds.Height;
rgbValuesWithClouds = new byte[bytes];
//copy color information to rgbValues array
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValuesWithClouds, 0, bytes);
//we are done copying so unlock bitmap. We dont need it anymore
bmpWithClouds.UnlockBits(bitmap_Data);
}
//using the using statement, bmpWithClouds bitmap is automatically disposed at the end of statement. No memory leaks :)
using (bmpWithoutClouds = new Bitmap(#"F:\Drive Backup\Samsung Galaxy S9\Danny Backup\Recovered data 02-10 18_32_36\1 (D) NTFS\C-Sharp\Weather Radar\WithoutClouds.bmp")) //24 bit bitmap
{
rect = new Rectangle(0, 0, bmpWithoutClouds.Width, bmpWithoutClouds.Height);
//Lock bitmap to copy its color information fast
bitmap_Data = bmpWithoutClouds.LockBits(rect, ImageLockMode.ReadWrite, bmpWithoutClouds.PixelFormat);
ptr = bitmap_Data.Scan0;
bytes = bitmap_Data.Stride * bmpWithoutClouds.Height;
rgbValuesWithoutClouds = new byte[bytes];
//copy color information to rgbValues array
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValuesWithoutClouds, 0, bytes);
//we are done copying so unlock bitmap. We dont need it anymore
bmpWithoutClouds.UnlockBits(bitmap_Data);
}
// Each position in these arrays, rgbValuesWithoutClouds and rgbValuesWithClouds, corresponds a color. eg
// First pixel Second pixel Third pixel Forth pixel .... // bitmaps
// B G R B G R B G R B G R .... // rgbValues arrays
bmptest = new Bitmap(512, 512);
cloudPoints = new List<Point>();
for (y = 0; y < wdthHght; y++)
{
j = 0;
for (x = 0; x < wdthHght; x++)
{
p = y * wdthHght * 3 + j;
if (rgbValuesWithClouds[p] != rgbValuesWithoutClouds[p])
{
cloudPoints.Add(new Point(x, y));
if (graphicsPath.IsVisible(x, y))
{
bmptest.SetPixel(x, y, Color.Yellow);
}
}
j += 3;
}
}
bmptest.Save(#"d:\bmptest1.bmp");
}
this method is being called in paint event
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawRectangle(Pens.Green, 0, 0, pictureBox1.Width - 1, pictureBox1.Height - 1);
Pen p = new Pen(Color.Red);
e.Graphics.DrawLine(p, 256, 0, 256, 512);
e.Graphics.DrawLine(p, 0, 256, 512, 256);
FindPoints();
DrawPieOnPicturebox(e.Graphics);
}
i found that if i'm not using or removing the part :
if (graphicsPath.IsVisible(x, y))
it will working fast but then it will color the pixels in yellow at once and i want it to color the pixels in yellow only if the graphicsPath is visible which make the whole application working very slow.
this is where and how i'm using the graphicsPath
public void DrawPieOnPicturebox(Graphics myPieGraphic)
{
Color myPieColors = Color.FromArgb(150, Color.LightGreen);
Size myPieSize = new Size((int)distanceFromCenterPixels, (int)distanceFromCenterPixels);
Point myPieLocation = new Point((pictureBox1.Width - myPieSize.Width) / 2, (pictureBox1.Height - myPieSize.Height) / 2);
DrawMyPie(myPiePercent, myPieColors, myPieGraphic, myPieLocation, myPieSize);
}
public void DrawMyPie(int myPiePerecent, Color myPieColor, Graphics myPieGraphic, Point
myPieLocation, Size myPieSize)
{
using (SolidBrush brush = new SolidBrush(myPieColor))
{
myPieGraphic.FillPie(brush, new Rectangle(myPieLocation, myPieSize), Convert.ToSingle(myPiePerecent * 360 / 100), Convert.ToSingle(15 * 360 / 100));
}
myPieGraphic.DrawImage(bmptest, Point.Empty);
graphicsPath.AddPie(new Rectangle(myPieLocation, myPieSize), Convert.ToSingle(myPiePerecent * 360 / 100), Convert.ToSingle(15 * 360 / 100));
}
in my unity3d project code i have this method : i want to use Bitmap GraphicsPath BitmapData Rectangle and more but they are all missing reference.
I tried to google for it some result suggest to change in the unity editor Project Settings > Player API Compatibility level to .NET 2.1 but it didn't much help. it did add some System.Drawing but not the csharp one.
a bit messed.
private void FindPoints()
{
Bitmap bmptest;
GraphicsPath gp = new GraphicsPath();
int x, y, p, j, wdthHght;
int bytes;
byte[] rgbValuesWithClouds;
byte[] rgbValuesWithoutClouds;
IntPtr ptr;
Rectangle rect;
BitmapData bitmap_Data;
Bitmap bmpWithClouds; //No memory is allocated
Bitmap bmpWithoutClouds; //No memory is allocated
gp.AddEllipse(new RectangleF(73, 72, 367, 367));
//using the using statement, bmpWithClouds bitmap is automatically disposed at the end of statement. No memory leaks :)
using (bmpWithClouds = new Bitmap(mymem))
{
rect = new Rectangle(0, 0, bmpWithClouds.Width, bmpWithClouds.Height);
wdthHght = bmpWithClouds.Width;
//Lock bitmap to copy its color information fast
bitmap_Data = bmpWithClouds.LockBits(rect, ImageLockMode.ReadWrite, bmpWithClouds.PixelFormat);
ptr = bitmap_Data.Scan0;
bytes = bitmap_Data.Stride * bmpWithClouds.Height;
rgbValuesWithClouds = new byte[bytes];
//copy color information to rgbValues array
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValuesWithClouds, 0, bytes);
//we are done copying so unlock bitmap. We dont need it anymore
bmpWithClouds.UnlockBits(bitmap_Data);
}
//using the using statement, bmpWithClouds bitmap is automatically disposed at the end of statement. No memory leaks :)
using (bmpWithoutClouds = new Bitmap(#"F:\Drive Backup\Samsung Galaxy S9\Danny Backup\Recovered data 02-10 18_32_36\1 (D) NTFS\C-Sharp\Weather Radar\WithoutClouds.bmp")) //24 bit bitmap
{
rect = new Rectangle(0, 0, bmpWithoutClouds.Width, bmpWithoutClouds.Height);
//Lock bitmap to copy its color information fast
bitmap_Data = bmpWithoutClouds.LockBits(rect, ImageLockMode.ReadWrite, bmpWithoutClouds.PixelFormat);
ptr = bitmap_Data.Scan0;
bytes = bitmap_Data.Stride * bmpWithoutClouds.Height;
rgbValuesWithoutClouds = new byte[bytes];
//copy color information to rgbValues array
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValuesWithoutClouds, 0, bytes);
//we are done copying so unlock bitmap. We dont need it anymore
bmpWithoutClouds.UnlockBits(bitmap_Data);
}
// Each position in these arrays, rgbValuesWithoutClouds and rgbValuesWithClouds, corresponds a color. eg
// First pixel Second pixel Third pixel Forth pixel .... // bitmaps
// B G R B G R B G R B G R .... // rgbValues arrays
bmptest = new Bitmap(512, 512);
cloudPoints = new List<Point>();
for (y = 0; y < wdthHght; y++)
{
j = 0;
for (x = 0; x < wdthHght; x++)
{
p = y * wdthHght * 3 + j;
if (rgbValuesWithClouds[p] != rgbValuesWithoutClouds[p])
{
cloudPoints.Add(new Point(x, y));
bmptest.SetPixel(x, y, Color.Red);
}
j += 3;
}
}
}
The following code behaves very oddly. It adds some extra spacing at the bottom of the image, and I can not see why. Result of code:
And this is the code that I am working with:
public static Image ReDraw(this Image main, int w, int h,
CompositingQuality quality = CompositingQuality.Default, //linear?
SmoothingMode smoothing_mode = SmoothingMode.None,
InterpolationMode ip_mode = InterpolationMode.NearestNeighbor)
{
//size
double dbl = (double)main.Width / (double)main.Height;
//preserve size ratio
if ((int)((double)h * dbl) <= w)
w = (int)((double)h * dbl);
else
h = (int)((double)w / dbl);
//draw
Image newImage = new System.Drawing.Bitmap(w, h);
Graphics thumbGraph = Graphics.FromImage(newImage);
thumbGraph.CompositingQuality = quality;
thumbGraph.SmoothingMode = smoothing_mode;
thumbGraph.InterpolationMode = ip_mode;
thumbGraph.Clear(Color.Transparent);
thumbGraph.DrawImage(main, 0, 0, w, h);
thumbGraph.DrawImage(main,
new System.Drawing.Rectangle(0, 0, w, h),
new System.Drawing.Rectangle(0, 0, main.Width, main.Height),
System.Drawing.GraphicsUnit.Pixel);
return newImage;
}
thumbGraph.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
I have a big image in good quality (for my needs), i need resize to small size (30 x 30px), I resize it with graphic.DrawImage. But when i resize it become blurred and little lighter.
also I have try CompositingQuality and InterpolationMode, but it all was bad.
Example, that quality i'm trying get.
My result
Edited
Image of icon i draw myself, maybe it will be better draw it small without resizing?
Edit2
Resizeing code:
Bitmap tbmp;
//drawing all my features in tbmp with graphics
bmp = new Bitmap(width + 5, height + 5);
bmp.MakeTransparent(Color.Black);
using (var gg = Graphics.FromImage(bmp))
{
gg.CompositingQuality = CompositingQuality.HighQuality;
// gg.SmoothingMode = SmoothingMode.HighQuality;
gg.InterpolationMode = InterpolationMode.HighQualityBicubic;
gg.DrawImage(tbmp, new Rectangle(0, 0, width, height), new Rectangle(GXMin, GYMin, GXMax + 20, GYMax + 20), GraphicsUnit.Pixel);
gg.Dispose();
}
I use this method as a way to get a thumbnail image (of any size) from an original (of any size). Note that there are inherent issues when you ask for a size ratio that varies greatly from that of the original. Best to ask for sizes that are in scale to one another:
public static Image GetThumbnailImage(Image OriginalImage, Size ThumbSize)
{
Int32 thWidth = ThumbSize.Width;
Int32 thHeight = ThumbSize.Height;
Image i = OriginalImage;
Int32 w = i.Width;
Int32 h = i.Height;
Int32 th = thWidth;
Int32 tw = thWidth;
if (h > w)
{
Double ratio = (Double)w / (Double)h;
th = thHeight < h ? thHeight : h;
tw = thWidth < w ? (Int32)(ratio * thWidth) : w;
}
else
{
Double ratio = (Double)h / (Double)w;
th = thHeight < h ? (Int32)(ratio * thHeight) : h;
tw = thWidth < w ? thWidth : w;
}
Bitmap target = new Bitmap(tw, th);
Graphics g = Graphics.FromImage(target);
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.High;
Rectangle rect = new Rectangle(0, 0, tw, th);
g.DrawImage(i, rect, 0, 0, w, h, GraphicsUnit.Pixel);
return (Image)target;
}
I am trying to print my form using GDI ,but when I print it ,the quality of the print is not that good(donknow whether Image getting aliased?) ,form size is 700x700 ,also there is one parameter which dint understood -raster op code-,here is code am using...
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics g1 = this.CreateGraphics();
System.Drawing.Image MyImage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height, g1);
Graphics g2 = Graphics.FromImage(MyImage);
IntPtr dc1 = g1.GetHdc();
IntPtr dc2 = g2.GetHdc();
BitBlt(dc2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, dc1, 0, 0, 13369376);
g1.ReleaseHdc(dc1);
g2.ReleaseHdc(dc2);
Bitmap bmp = new Bitmap(MyImage);
int x = e.MarginBounds.X;
int y = e.MarginBounds.Y;
int width = bmp.Width;
int height = bmp.Height;
if ((width / e.MarginBounds.Width) > (height / e.MarginBounds.Height))
{
width = e.MarginBounds.Width;
height = bmp.Height * e.MarginBounds.Width / bmp.Width;
}
else
{
height = e.MarginBounds.Height;
width = bmp.Width * e.MarginBounds.Height / bmp.Height;
}
System.Drawing.Rectangle destRect = new System.Drawing.Rectangle(x, y, width, height);
e.Graphics.DrawImage(bmp, destRect, 0, 0, bmp.Width, bmp.Height, System.Drawing.GraphicsUnit.Pixel);
}
Maybe you have a problem with the original image. Give me a link to an image. Check the image size.
Try insert line
g2.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
Good luck!
It is normal that the result will be scaled and aliased. The source has too few pixels compared to the resolution of a modern printer.
Consider using WPF, that uses a vector based rendering thus there's no loss/distortion when scaling.
Cheers