estoy tratando de editar los píxeles de una 8bpp. Desde este PixelFormat está indexada soy consciente de que se utiliza una Tabla de Colores para asignar los valores de los píxeles. A pesar de que pueden modificar el mapa de bits mediante la conversión de 24 bpp, 8bpp la edición es mucho más rápido (13ms vs 3ms). Pero, de cambiar cada valor cuando se accede a la 8bpp de mapa de bits resultados en algunos aleatoria de colores rgb aunque el PixelFormat sigue siendo 8bpp.

Actualmente estoy desarrollando en c# y el algoritmo es como sigue:

(C#)

1 – Carga de mapa de bits original en 8bpp

2 – Crear Vacío temp de mapa de bits con 8bpp con el mismo tamaño que el original

3-LockBits de mapas de bits y, con P/Invoke, llamada método de c++ donde paso el Scan0 de cada objeto BitmapData. (He utilizado un método de c++, ya que ofrece un mejor rendimiento cuando se itera a través de los píxeles del mapa de bits)

(C++)

4 – Crear un int[256] paleta de acuerdo a algunos parámetros y modificar la temperatura de mapa de bits, bytes, pasando de los originales de los valores de píxeles a través de la paleta.

(C#)

5 – UnlockBits.

Mi pregunta es ¿cómo puedo editar los valores de los píxeles sin tener la extraña colores rgb, o mejor aún, editar el 8bpp de mapa de bits de la Tabla de Colores?

InformationsquelleAutor Pedro Sá | 2010-04-07

3 Comentarios

  1. 10

    No hay ninguna necesidad de avanzar en C++ de la tierra o el uso P/Invoke en absoluto; C# soporta punteros y código inseguro perfectamente bien; incluso puede aventurar una conjetura que esta es la causa de sus problemas.

    Los colores son probablemente provenga de la Paleta predeterminada. Usted encontrará que el cambio de la Paleta no debe ser lento en todo. Esto es lo que tengo que hacer para crear una paleta de escala de grises:

    image = new Bitmap( _size.Width, _size.Height, PixelFormat.Format8bppIndexed);
    ColorPalette pal = image.Palette;
    for(int i=0;i<=255;i++) {
        //create greyscale color table
        pal.Entries[i] = Color.FromArgb(i, i, i);
    }
    image.Palette = pal; //you need to re-set this property to force the new ColorPalette
    • ¿Cómo aplicar la nueva paleta de la imagen anterior? Acerca de cómo cambiar el tamaño de la imagen anterior así?
    • Sólo tienes que configurar el Palette propiedad de la espalda. Cambiar el tamaño de una imagen es diferente, utilice Graphics.DrawImage en una nueva imagen de la derecha dumensions para que.
    • Gráficos.DrawImage no es compatible con formatos de píxeles indizado, y convertir a los no-indexada niega la ventaja de velocidad de indexado utilizando formatos.
  2. 2

    Imagina que tu indexado 8ppp graysacle se almacenan en una matriz lineal datosb (para la velocidad)

    Prueba este código:

    //Create 8bpp bitmap and look bitmap data
    bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
    bmp.SetResolution(horizontalResolution, verticalResolution);
    bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
    
    //Create grayscale color table
    ColorPalette palette = bmp.Palette;
    for (int i = 0; i < 256; i++)
        palette.Entries[i] = Color.FromArgb(i, i, i);
    bmp.Palette = palette;
    
    //write data to bitmap
    int dataCount = 0;
    int stride = bmpData.Stride < 0 ? -bmpData.Stride : bmpData.Stride;
    unsafe
    {
        byte* row = (byte*)bmpData.Scan0;
        for (int f = 0; f < height; f++)
        {
            for (int w = 0; w < width; w++)
            {
                row[w] = (byte)Math.Min(255, Math.Max(0, dataB[dataCount]));
                dataCount++;
            }
            row += stride;
        }
    }
    
    //Unlock bitmap data
    bmp.UnlockBits(bmpData);
  3. 1

    Has probado a cargar un System.Drawing.Image lugar? Que clase te da acceso a la paleta de colores. Usted puede, a continuación, ajustar el System.Drawing.Image como un System.Drawing.Bitmap una vez que la paleta se establece.

    No estoy seguro de cómo System.Drawing.BitMap.SetPixel() trabaja con indexados de color de las imágenes. Podría ser que intenta mapa es el más cercano de color en la paleta.

    • Gracias por tu respuesta. Sé que puedo modificar el mapa de bits de la paleta cambiando el mapa de bits de la Paleta de propiedades. Pero esto es demasiado lento. Tenía la esperanza de que alguien me pudiera decir cómo acceder a la Tabla de Color del puntero para que yo pudiera modificarlo directamente. SetPixel no funciona y es también muy lento. lo que yo no entiendo es por qué el píxel se le asigna un color rgb cuando cambio es un valor entre 0 (negro) a 100 (debe ser de color gris, pero es de color rojo).
    • Um. Bitmap hereda de Image… y por lo tanto tiene la misma Paleta. Y usted puede copiar paletas simplemente con bm2.Palette = bm1.Palette.

Dejar respuesta

Please enter your comment!
Please enter your name here