NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
Avatar
jt.e
Člen
Avatar
jt.e:6.3.2016 9:42

Ahoj, mám takový problém s BitmapData.
bitmap.LockBits vyhazuje u některých obrázků chybu
"V rozhraní GDI+ došlo k obecné chybě.".
Nevíte co můžu mít špatně?

public static void Gradient(ref Bitmap bitmap)
{
    if (bitmap == null) return;
    try
    {
        BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                         ImageLockMode.ReadWrite,
                         PixelFormat.Format24bppRgb);
        unsafe
        {
            BGR* rgb = (BGR*)bd.Scan0;

            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    int pos = (y * bitmap.Width) + x;
                    rgb[pos] = SetBlackAndWhite(rgb[pos]);
                }
            }
        }
        bitmap.UnlockBits(bd);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Chyba při aplikaci efektu!", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

Náhledy při krokování před zavoláním .LockBits a po:

 
Odpovědět
6.3.2016 9:42
Avatar
Petr Čech
Tvůrce
Avatar
Odpovídá na jt.e
Petr Čech:6.3.2016 10:10

Hoď sem inicializaci té bitmapy. Paletu v konstruktoru nastav na null.

Nahoru Odpovědět
6.3.2016 10:10
the cake is a lie
Avatar
jt.e
Člen
Avatar
Odpovídá na Petr Čech
jt.e:6.3.2016 10:30

máš pravdu chyba je tady:

zpracovavanabitmapa = bmp.Clone(new Rectangle(0, 0, bmp.Width, bmp.Height), PixelFormat.Format24bppRgb);

pokud to udělám pouze takto:

zpracovavanabitmapa = bmp;

tak je to OK.

ale já potřebuji nějak udělat klon

 
Nahoru Odpovědět
6.3.2016 10:30
Avatar
jt.e
Člen
Avatar
jt.e:6.3.2016 10:39

Takto to funguje:

zpracovavanabitmapa = new Bitmap(bmp);
 
Nahoru Odpovědět
6.3.2016 10:39
Avatar
Petr Čech
Tvůrce
Avatar
Nahoru Odpovědět
6.3.2016 12:31
the cake is a lie
Avatar
jt.e
Člen
Avatar
Odpovídá na Petr Čech
jt.e:6.3.2016 13:20

Díky za pomoc.

Už jsem to klonování myslím opravil:

public static Bitmap CloneBitmap(Bitmap src)
        {
            if(src!=null)
            {
                try
                {
                    Rectangle rect = new Rectangle(0, 0, src.Width, src.Height);
                    Bitmap bmp = new Bitmap(rect.Width, rect.Height);
                    Graphics g = Graphics.FromImage(bmp);
                    g.DrawImage(src, 0, 0, rect, GraphicsUnit.Pixel);
                    g.Dispose();
                    return bmp;
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message, "Chyba při kopírování bitmapy!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
         return null;
        }

Tohle se zdá být funkční.

Jak jsem výše uvedl, tak ani zpracovavanabit­mapa = new Bitmap(bmp); nefungovala úplně správně, protože měnila PixelFormat na 32bit.

 
Nahoru Odpovědět
6.3.2016 13:20
Avatar
jt.e
Člen
Avatar
jt.e:6.3.2016 13:36

jo a tu funkci jsem měl taky špatně, tady je to správně:

public static unsafe void Gradient(ref Bitmap bitmap)
{
    if (bitmap == null) return;
    try
    {
        BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                         ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

        for (int y = 0; y < bitmap.Height; y++)
        {
            byte* bytes = (byte*)bd.Scan0.ToPointer() + y * Math.Abs(bd.Stride);
            BGR* bgr = (BGR*)bytes;
            for (int x = 0; x < bitmap.Width; x++)
            {
                SetBlackAndWhite(ref bgr[x]);
            }
        }

        bitmap.UnlockBits(bd);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Chyba při aplikaci efektu!", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

v té puvodní je problém se zarovnáním.

Ale tohle vypadá divně:

byte* bytes = (byte*)bd.Scan0.ToPointer() + y * Math.Abs(bd.Stride);
            BGR* bgr = (BGR*)bytes;
Editováno 6.3.2016 13:37
 
Nahoru Odpovědět
6.3.2016 13:36
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.