Растровый объект C #, цвет выглядит прозрачным - PullRequest
6 голосов
/ 08 марта 2012

Я работаю над программой на C #, которая делает скриншоты зелья на экране пользователя.По большей части это работает как надо, но я недавно столкнулся с одной проблемой.Кажется, что есть (по крайней мере) один пиксельный цвет, который всегда выглядит прозрачным в выходном изображении.Любой экземпляр цвета # 0D0B0C (RGB 13, 11, 12) выглядит прозрачным в сохраненном png.Это с PixelFormat, установленным в Format32bppArgb.Если я установлю его на Format32bppRgb или Format24bppRgb, тот же цвет пикселя будет выглядеть черным в сохраненном png.

Я понятия не имею, что может быть причиной, но единственное, что я смог сделать, -fix "это очистить графический объект от этого цвета перед выполнением CopyFromScreen ().Я не хочу этого делать по нескольким причинам.Во-первых, я не знаю, является ли это единственным цветом, который имеет проблему (что с 16 777 216 цветами, есть довольно много возможностей), и во-вторых, я ненавижу исправления взлома, это похоже на исправление взлома.

МожетКто-нибудь пролил свет на то, что может быть причиной этой проблемы?Я запутался с PixelFormat при создании растрового изображения и с CopyPixelOperation в методе CopyFromScreen, похоже, ничего не работает.Тот факт, что очистка графического объекта до этого цвета «исправляет», кажется, говорит мне, что прозрачность исходит от самих данных экрана, но это не имеет смысла.Я слишком долго смотрел на это, думаю, мне нужен свежий взгляд на это.Если у кого-нибудь есть идея, почему это может происходить, я бы хотел это услышать.Спасибо.

Ответы [ 4 ]

1 голос
/ 08 марта 2012

Альфа-значение может быть 0?Вы проверяли это?

Потому что разница между Format32bppArgb и Format32bppRgb в том, что второй формат не знает альфа-канал.

0 голосов
/ 11 мая 2016

Мне просто нужно было запросить CopyFromScreen в растровое изображение, которое вообще не имеет альфа-канала, например:

Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height,     System.Drawing.Imaging.PixelFormat.Format32bppRgb);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(bounds.Location, new Point(0, 0), bitmap.Size);

Я подтвердил, что у него есть прозрачные пиксельные дыры с Format32bppArgb, но не с Format32bppRgb

0 голосов
/ 19 апреля 2012

Возникла точно такая же проблема при рендеринге элемента управления растровому изображению. Удалось исправить это, создав еще одно растровое изображение с PixelFormat.Format32bppRgb и добавив BitBlt к нему. Надеюсь, это поможет!

public class ScreenCapture
{
    [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
    private static extern bool BitBlt(
        IntPtr hdcDest, // handle to destination DC
        int nXDest, // x-coord of destination upper-left corner
        int nYDest, // y-coord of destination upper-left corner
        int nWidth, // width of destination rectangle
        int nHeight, // height of destination rectangle
        IntPtr hdcSrc, // handle to source DC
        int nXSrc, // x-coordinate of source upper-left corner
        int nYSrc, // y-coordinate of source upper-left corner
        System.Int32 dwRop // raster operation code
        );


    /// <summary>
    /// Returns an image of the control
    /// </summary>
    /// <param name="control">The control object whose image is wanted</param>
    /// <returns>Image of the control</returns>
    /// <remarks>This is based on code from 
    /// http://www.dotnet247.com/247reference/a.aspx?u=http://www.c-sharpcorner.com/Code/2002/April/ScreenCaptureUtility.asp 
    /// with changes made to prevent 0D0B0C transparency issues</remarks>
    public static Image GetControlImage(Control control)
    {
        Graphics g1 = control.CreateGraphics();

        // Create a bitmap the same size as the control
        Image MyImage = new Bitmap(control.ClientRectangle.Width, control.ClientRectangle.Height, PixelFormat.Format32bppRgb);
        (MyImage as Bitmap).SetResolution(g1.DpiX, g1.DpiY);

        Graphics g2 = Graphics.FromImage(MyImage);

        IntPtr dc1 = g1.GetHdc();
        IntPtr dc2 = g2.GetHdc();

        // BitBlt from one DC to the other
        BitBlt(dc2, 0, 0, control.ClientRectangle.Width, control.ClientRectangle.Height, dc1, 0, 0, 13369376);

        // Release Device Contexts
        g1.ReleaseHdc(dc1);
        g2.ReleaseHdc(dc2);

        // This statement runs the garbage collector manually
        // (If not present, uses up large amounts of memory...)
        GC.Collect();

        return MyImage;
    }
}
0 голосов
/ 08 марта 2012

Похоже, у вас на экране плохой пиксель.

...