开发者

Capture screen in C# for resolution (1366 by 768) in error

I got this error only for the resolution 1366x768. It woks fine for any other higher or lower resolutions. I captured the Screen by invoking system calls. The received bmp I directly save and it worked fine. But then I converts it to a byte stream. After covering to a byte stream I again tried to save the image just for debugging purposes but it failed.

Code that i used to convert th开发者_StackOverflowe bmp to byte is as follows

private static byte[] BmpToBytes_MemStream(Bitmap bmp)
    {
        byte[] dst = new byte[(Screen.PrimaryScreen.Bounds.Width * Screen.PrimaryScreen.Bounds.Height) + 1078];
        try
        {
            MemoryStream stream = new MemoryStream();
            bmp.Save(stream, ImageFormat.Bmp);
            Buffer.BlockCopy(stream.GetBuffer(), 0, dst, 0, dst.Length);
            bmp.Dispose();
            stream.Close();
        }
        catch (Exception exception)
        {
            throw exception;
        }
        return dst;
    }

Code that i used convert this byte stream back to bmp is as follows,

using (MemoryStream ms = new MemoryStream(fullframe))
            {
                Bitmap bmp = (Bitmap)Image.FromStream(ms);
                bmp.Save(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" + frame.ToString() + ".bmp", ImageFormat.Bmp);
            }

And the error I get is as follows

Error: System.ArgumentException: Parameter is not valid. at System.Drawing.Image.FromStream(Stream stream, Boolean useEmbeddedColorManagement, Boolean validateImageData) at System.Drawing.Image.FromStream(Stream stream)

It will be great if anyone of you can point me where the error is and how to correct it.


I'm not sure if you have to use your code, but this is far simpler:

public static Image CaptureScreen(Rectangle bounds, int x, int y)
{
    Bitmap target = new Bitmap(bounds.Width, bounds.Height);
    Graphics.FromImage(target).CopyFromScreen(x, y, 0, 0, new Size(bounds.Width, bounds.Height));

    return (target);
}

public static byte[] ImageToByteArray(Image value)
{
    return ((byte[])new ImageConverter().ConvertTo(value, typeof(byte[])));
}

You can use them like so:

Image i = CaptureScreen(Screen.PrimaryScreen.Bounds, 0, 0);
byte[] b = ImageToByteArray(i);


Most likely a padding issue. I expect each line to start at a 4 byte boundary. This implies two byte padding per line at this resolution.

But your BmpToBytes_MemStream is extremely strange. It surprises me that it actually works ever.

  • dst only contains a byte per pixel. True color requires 3-4 bytes per pixel
  • It disregards bitmap header, padding,...
  • 1078 is a magic number without justification
  • Thus there is no reason to assume that the size of the saved bitmap and the size of dst are related in any way
  • There is MemoryStream.ToArray() which gives you a new array with exactly the size of the saved bitmap
  • You're using the catch-throw and lose the stacktrace antipattern. You can use throw; to rethrow an exception without losing the stacktrace.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜