Created
May 8, 2020 18:00
-
-
Save Zerumi/f3b03bf7770d593707f585cf816b5b71 to your computer and use it in GitHub Desktop.
GDI Problem (for pizhikcoder)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.ComponentModel; | |
using System.Diagnostics; | |
using System.Drawing; | |
using System.Drawing.Drawing2D; | |
using System.Drawing.Imaging; | |
using System.IO; | |
using System.Runtime.InteropServices; | |
using System.Windows; | |
using System.Windows.Forms; | |
namespace ScreenSharing | |
{ | |
class Program | |
{ | |
// держи пару полезных ссылок, которые могут помочь | |
/* | |
* http://www.pinvoke.net/default.aspx/gdi32.BitBlt // метод pinvoke | |
* https://www.cyotek.com/blog/capturing-screenshots-using-csharp-and-p-invoke // способ который нельзя сделать на Win7 SP1, так как старая версия | |
* https://stackoverflow.com/questions/23026222/a-generic-error-occurred-in-gdi-using-c-sharp // первый вопрос | |
* https://stackoverflow.com/questions/39530513/gdi-error-when-calling-image-fromhbitmap-on-handle-returned-by-loadimage // второй | |
* https://stackoverflow.com/questions/2286722/generic-error-in-gdi-when-calling-bitmap-gethbitmap // третий | |
* https://stackoverflow.com/questions/1053052/a-generic-error-occurred-in-gdi-jpeg-image-to-memorystream // четвертый | |
*/ | |
// способ до комментированных строк кода занимает ~10мс | |
// Не учитывается время на переписывание в данные для отправки на сервер | |
[STAThread] | |
static void Main(string[] args) | |
{ | |
Stopwatch stopwatch = new Stopwatch(); | |
stopwatch.Start(); | |
int width = Convert.ToInt32(System.Windows.SystemParameters.PrimaryScreenWidth); | |
int height = Convert.ToInt32(System.Windows.SystemParameters.PrimaryScreenHeight); | |
Bitmap bmp = new Bitmap(width,height); | |
IntPtr pTarget = Graphics.FromImage(bmp).GetHdc(); | |
IntPtr pSource = CreateCompatibleDC(pTarget); | |
if(!BitBlt(pTarget, 0, 0, width, height, pSource, 0, 0, TernaryRasterOperations.SRCCOPY)) | |
{ | |
throw new Win32Exception(); | |
} | |
DeleteDC(pSource); | |
System.Windows.MessageBox.Show(Convert.ToString(stopwatch.ElapsedMilliseconds)); | |
Bitmap result = Image.FromHbitmap(pTarget); | |
byte[] arr; | |
using(var stream = new MemoryStream()) | |
{ | |
result.Save(stream, ImageFormat.Jpeg); | |
arr = stream.ToArray(); | |
} | |
} | |
[DllImport("gdi32.dll")] | |
public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, | |
int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop); | |
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] | |
static extern IntPtr CreateCompatibleDC(IntPtr hdc); | |
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] | |
static extern bool DeleteDC(IntPtr hdc); | |
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] | |
static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); | |
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] | |
static extern bool DeleteObject(IntPtr hObject); | |
public enum TernaryRasterOperations : uint | |
{ | |
SRCCOPY = 0x00CC0020, | |
SRCPAINT = 0x00EE0086, | |
SRCAND = 0x008800C6, | |
SRCINVERT = 0x00660046, | |
SRCERASE = 0x00440328, | |
NOTSRCCOPY = 0x00330008, | |
NOTSRCERASE = 0x001100A6, | |
MERGECOPY = 0x00C000CA, | |
MERGEPAINT = 0x00BB0226, | |
PATCOPY = 0x00F00021, | |
PATPAINT = 0x00FB0A09, | |
PATINVERT = 0x005A0049, | |
DSTINVERT = 0x00550009, | |
BLACKNESS = 0x00000042, | |
WHITENESS = 0x00FF0062, | |
CAPTUREBLT = 0x40000000 //only if WinVer >= 5.0.0 (see wingdi.h) | |
} | |
// способ ниже занимает ~85 мс | |
//stopwatch.Start(); | |
//var size = Screen.PrimaryScreen.Bounds.Size; | |
//Bitmap bmp = new Bitmap(size.Width, size.Height); | |
//Graphics graph = Graphics.FromImage(bmp); | |
//graph.CopyFromScreen(0, 0, 0, 0, new Size(size.Width, size.Height)); | |
//graph.CompositingQuality = CompositingQuality.HighQuality; | |
//graph.SmoothingMode = SmoothingMode.HighQuality; | |
//graph.InterpolationMode = InterpolationMode.HighQualityBicubic; | |
//MemoryStream ms = new MemoryStream(); | |
//bmp.Save(ms, ImageFormat.Png); | |
//byte[] imagebt = new byte[3110400]; | |
//imagebt = ms.ToArray(); | |
//stopwatch.Stop(); | |
//System.Windows.MessageBox.Show(Convert.ToString(stopwatch.ElapsedMilliseconds)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment