vectorial para necesarios mapa library imagen formatos entre elementos ejemplo diferencia dibujar crear c# bitmap stride

mapa - elementos necesarios para dibujar un pixel en c#



¿Cómo puedo copiar los datos de píxeles de un mapa de bits con paso negativo? (5)

De la documentación de C # en BitmapData: La zancada es el ancho de una sola fila de píxeles (una línea de exploración), redondeada a un límite de cuatro bytes. Si la zancada es positiva, el mapa de bits es de arriba hacia abajo. Si el paso es negativo, el mapa de bits es de abajo hacia arriba

Estaba buscando la forma más rápida de convertir un mapa de bits a 8bpp. Encontré 2 maneras:

1.

public static System.Drawing.Image ConvertTo8bpp(Bitmap oldbmp) { using (var ms = new MemoryStream()) { oldbmp.Save(ms, ImageFormat.Gif); ms.Position = 0; return System.Drawing.Image.FromStream(ms); } }

2. http://www.wischik.com/lu/programmer/1bpp.html

Pero: 1. Resultados en un resultado de muy baja calidad (mala plataforma)

y 2 me da un mapa de bits con paso negativo, cuando trato de bloquear los bits y copiar los datos a una matriz de bytes obtengo una excepción: intenté leer o escribir en la memoria protegida. Esto a menudo es una indicación de que otra memoria está corrupta.

BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat); this.stride = bmpData.Stride; this.bytesPerPixel = GetBytesPerPixel(bmp.PixelFormat); int length = bmpData.Stride * bmp.Height; if (this.stride < 0) this.data = new byte[-length]; else this.data = new byte[length]; Marshal.Copy(bmpData.Scan0, data, 0, length); //Unlock the bitmap bmp.UnlockBits(bmpData);

¿Cómo puedo hacer que 2 dé un paso positivo? ¿O cómo puedo copiar datos usando bits de bloqueo de una zancada negativa?


Copie 1 fila a la vez, calculando el puntero inicial de una fila como ((byte*)scan0 + (y * stride)) . El código será idéntico para la zancada positiva o negativa.


No sé por qué hay algo extraño en el mapa de bits creado por el método FromHbitmap , pero sé que puedes arreglarlo usando Bitmap bmpClone = (Bitmap)bmp.Clone(); y haciendo los LockBits en bmpClone.

Además, descubrí que si usas bmp.Clone() , no puedes eliminar () de bmp hasta que hayas terminado con el clon.

Esto también funciona y le permite deshacerse de la imagen de zancada negativa más temprano que tarde:

Bitmap bmp = null; using (Bitmap bmpT = CopyToBpp(bmpO, 1)) { bmp = new Bitmap(bmpT); }


Supongo que la excepción que recibes se debe a

this.data = new byte[-length];

Y luego, tratando de copiar datos en una matriz de bytes de tamaño negativo (no veo cómo eso incluso compila realmente ...).


El problema aquí es que Scan0 apunta al comienzo de la primera línea de exploración, no al comienzo del primer byte de datos. En un mapa de bits ascendente, la primera línea de escaneo son los bytes Stride desde el final de los datos del mapa de bits.

Cuando llame a Marshal.Copy Copie los datos desde Scan0 , intenta copiar (Height*Stride) bytes, comenzando desde la posición ((Height-1)*Stride) . Claramente, eso se va a llevar a las malas hierbas.

Si solo quiere copiar los datos del mapa de bits, debe calcular la dirección de inicio con Scan0 - (Height-1)*Stride . Eso lo iniciará al comienzo de los datos del mapa de bits. Puede pasar esa dirección calculada a Marshal.Copy . Marshal.Copy .

Si desea copiar las líneas de escaneo en orden (es decir, arriba, siguiente, siguiente, ... abajo), entonces tiene que copiar una línea a la vez: copie los bytes Stride de Scan0 , luego agregue Stride (que es negativo), copie esa línea, etc. Rick Brewster tenía la respuesta correcta allí: https://.com/a/10360753/56778