Frage

Ich bin derzeit mit Brendan Tompkins ImageQuantization dll.

War es hilfreich?

Lösung

Es sollte möglich sein, den Code mit Marshal mit expliziten Lesen des zugrunde liegenden Stream über so etwas wie Binary zu ersetzen. Dies kann langsamer sein, da Sie den Strom vollständig in die verwalteten Speicher oder sucht in sie lieber lesen muss auf der Kopie bereits in nicht verwalteten Speichern als Berufung schnell zugänglich zu sein, aber ist im Grunde Ihre einzige Option.

Sie können nicht einfach gehen von einem Medium Vertrauenskontext in der nicht verwalteten Speicher spelunking, wenn auch nur Leseoperationen durchführen.

Nachdem auf dem verknüpften Code sieht es gibt einen Grund Sie diese Art der Sache nicht tun dürfen. Für den Anfang, er ignoriert den 64/32-Bit-Aspekt der IntPtr!

Die zugrunde liegende Bitmapdata-Klasse benutzt er völlig auf unbeschränkten Lesezugriff auf beliebige Speicherausgesagt wird, dies geschieht nie unter mittlerem Vertrauen.
Ein signifikantes Umschreiben seiner Basisfunktionalität wird entweder erforderlich, direkt Bitmap zu verwenden (mit den langsamen GetPixel Anrufen) oder die Daten direkt über konventionellen Strom apis zu lesen, es in ein Array (s) fallen lassen und es dann selbst parsen. Keine von diesen sind wahrscheinlich angenehm. Erstere wird viel langsamer (ich würde Größenordnung aufgrund der hohen Overhead pro Pixel Lese erwarten), die später weniger langsam (wenn auch noch langsamer), aber hat viel mehr im Zusammenhang Anstrengungen in Bezug auf das niedrige Niveau Parsen der Bilddaten Umschreiben .

Hier ist eine grobe Angabe, was Sie auf dem aktuellen Code ändern müssen basiert:

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

Sie müssen in etwa das gleiche in den anderen Funktionen zu tun. Dadurch entfällt jegliche Notwendigkeit für Color32, wird die Bitmap-Klasse mit allen damit umgehen für Sie.

Bitmap.SetPixel() wird mit dem zweiten Durchgang befassen. Beachten Sie, dass dies der einfachste Weg zum Hafen Ding ist aber absolut nicht der schnellste Weg, um es in einem Medium Vertrauen Umwelt zu tun.

scroll top