¿Hay alguna manera de hacer Cuantificación imagen de forma segura y sin cálculo de referencias?

StackOverflow https://stackoverflow.com/questions/1099655

Pregunta

Actualmente estoy usando Brendan Tompkins ImageQuantization DLL. http://codebetter.com/blogs/brendan.tompkins/archive/2007/06/14/gif-image-color-quantizer-now-with-safe-goodness.aspx

Pero no se ejecuta en la confianza medio en asp.net.

¿Alguien sabe de una biblioteca de cuantificación de imagen que se ejecuta en fideicomiso medio?

Actualizar No me importa si la solución es lenta. Sólo necesito algo que funciona.

¿Fue útil?

Solución

Usted debe ser capaz de reemplazar el código usando Mariscal con la lectura explícita de la secuencia subyacente a través de algo así como BinaryReader. Esto puede ser más lenta ya que debe leer la secuencia del todo en su memoria administrada o buscar en ella en lugar de confiar en la copia que ya están en la memoria no administrada ser rápidamente accesible, pero es fundamentalmente su única opción.

Usted simplemente no puede ir a la espeleología en la memoria no administrada desde un contexto de confianza medio, aunque sólo realizar operaciones de lectura.

Después de examinar el código relacionado hay una razón para que no se nos permite hacer este tipo de cosas. Para empezar está ignorando el aspecto 64/32 bits de la IntPtr!

La clase BitmapData subyacente que está usando se predica por completo de tener acceso de lectura sin restricciones a la memoria arbitraria, esto nunca sucede bajo de confianza medio.
Será necesaria una reescritura importante de su funcionalidad básica para cualquiera que use memoria de imagen de forma directa (con las llamadas GetPixel lentos) o leer los datos directamente a través de las API de corriente convencionales, colocándolo en un array (s) y luego analizar usted mismo. Ninguno de estos son propensos a ser agradable. El primero será mucho más lento (I esperaría orden de magnitud debido a la alta sobrecarga por lectura de píxeles), la tarde menos lento (aunque sigue siendo más lento) pero mucho más se ha asociado esfuerzo en términos de volver a escribir el análisis de bajo nivel de los datos de imagen .

He aquí una guía aproximada de lo que hay que cambiar en función de la actual código:

desde Quantizer.cs

public Bitmap Quantize(Image source)
{
    // Get the size of the source image
    int height = source.Height;
    int width = source.Width;
    // And construct a rectangle from these dimensions
    Rectangle bounds = new Rectangle(0, 0, width, height);
    // First off take a 32bpp copy of the image
    Bitmap copy = new Bitmap(width, height, PixelFormat.Format32bppArgb);
    // And construct an 8bpp version
    Bitmap output = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
    // Now lock the bitmap into memory
    using (Graphics g = Graphics.FromImage(copy))
    {
        g.PageUnit = GraphicsUnit.Pixel;
        // Draw the source image onto the copy bitmap,
        // which will effect a widening as appropriate.
            g.DrawImage(source, bounds);
    }

    //!! BEGIN CHANGES - no locking here
    //!! simply use copy not a pointer to it
    //!! you could also simply write directly to a buffer then make the final immage in one go but I don't bother here

    // Call the FirstPass function if not a single pass algorithm.
    // For something like an octree quantizer, this will run through
    // all image pixels, build a data structure, and create a palette.
    if (!_singlePass)
        FirstPass(copy, width, height);

    // Then set the color palette on the output bitmap. I'm passing in the current palette 
    // as there's no way to construct a new, empty palette.
    output.Palette = GetPalette(output.Palette);
    // Then call the second pass which actually does the conversion
    SecondPass(copy, output, width, height, bounds);
    //!! END CHANGES
    // Last but not least, return the output bitmap
    return output;
}

//!! Completely changed, note that I assume all the code is changed to just use Color rather than Color32
protected  virtual void FirstPass(Bitmap source, int width, int height)
{
    // Loop through each row
    for (int row = 0; row < height; row++)
    {
        // And loop through each column
        for (int col = 0; col < width; col++)
        {            
            InitialQuantizePixel(source.GetPixel(col, row)); 
        }   // Now I have the pixel, call the FirstPassQuantize function...
    }
}

lo que se necesita hacer más o menos lo mismo en las otras funciones. Así se elimina la necesidad de Color32, la clase Bitmap se ocupará de todo lo que para usted.

Bitmap.SetPixel() se ocupará de la segunda pasada. Tenga en cuenta que esta es la forma más fácil de las cosas del puerto, pero de ninguna manera la forma más rápida de hacerlo dentro de un entorno de confianza medio.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top