Domanda

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

Ma non viene eseguito in attendibilità media in asp.net.

Qualcuno sa di una libreria Immagine di quantizzazione che viene eseguito in attendibilità media?

Aggiorna Non mi importa se la soluzione è lento. Ho solo bisogno di qualcosa che funziona.

È stato utile?

Soluzione

Si dovrebbe essere in grado di sostituire il codice utilizzando maresciallo con lettura esplicita del torrente sottostante via qualcosa come BinaryReader. Questo potrebbe essere più lento in quanto è necessario leggere il flusso del tutto nella vostra memoria gestito o cercare in esso piuttosto che basarsi sulla copia già in memoria non gestita essere rapidamente accessibile, ma è fondamentalmente l'unica opzione.

Semplicemente non si può andare speleologia nella memoria non gestita da un contesto di fiducia di media, anche se solo l'esecuzione di operazioni di lettura.

Dopo aver guardato il codice legato c'è una ragione per cui non è permesso di fare questo genere di cose. Per cominciare ha ignorando l'aspetto 64 / 32bit del IntPtr!

Il sottostante classe BitmapData sta usando è assolutamente necessario innanzitutto avere accesso in lettura illimitato alla memoria arbitrario, questo non è mai accadendo sotto attendibilità media.
Una riscrittura significativa della sua funzionalità di base sarà necessario usare sia per BitMap di direttamente (con le chiamate GetPixel lente) o leggere i dati direttamente tramite API streaming convenzionali, cadere in un array (s) e quindi analizzare fuori da soli. Nessuno di questi sono suscettibili di essere piacevole. Il primo sarà molto più lento (mi aspetterei ordine di grandezza a causa della forte sovraccarico per lettura pixel), il più tardi meno lento (anche se ancora più lento), ma è molto di più associata sforzo in termini di riscrivere il parsing basso livello di dati di immagine .

Ecco una guida approssimativa a ciò che è necessario cambiare in base al codice corrente:

da 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...
    }
}

si avrebbe bisogno di fare più o meno lo stesso in altre funzioni. Ciò elimina ogni necessità di Color32, la classe Bitmap si occuperà di tutto ciò che per voi.

Bitmap.SetPixel() si occuperà il secondo passaggio. Si noti che questo è il modo più semplice per le cose di porta, ma non è assolutamente il modo più veloce per farlo all'interno di un ambiente di fiducia medio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top