Есть ли способ сделать изображение квантования безопасно и без Marshalling?

В настоящее время я использую dll dll. http://codebetter.com/blogs/brendan.tompkins/archive/2007/06/14/gif-image-color-quantizer-now-with-safe-goodness.aspx

Но он не работает в среде доверия в asp.net.

Кто-нибудь знает библиотеку Image Quantization, которая работает в среде доверия?

Обновление меня не волнует, если решение идет медленно. Мне просто нужно что-то, что работает.

Вы должны иметь возможность заменить код с помощью маршала явным чтением базового streamа через что-то вроде BinaryReader. Это может быть медленнее, так как вы должны полностью прочитать stream в свою управляемую память или искать в нем, а не полагаться на то, что копия, уже находящаяся в неуправляемой памяти, быстро доступна, но в принципе является вашим единственным вариантом.

Вы просто не можете перейти в неуправляемую память из контекста среднего доверия, даже если выполняете только операции чтения.

Посмотрев на связанный код, есть причина, по которой вам не разрешено делать подобные вещи. Для начала он игнорирует 64/32-битный аспект IntPtr!

Базовый class BitMapData, который он использует, полностью основан на свободном доступе чтения к произвольной памяти, это никогда не происходит под средним доверием.
Значительная переработка его базовой функциональности потребует либо напрямую использовать BitMap (с медленными вызовами GetPixel), либо читать данные напрямую через обычный stream apis, отбрасывая его в массив (ы), а затем самостоятельно анализировать. Ни один из них, вероятно, не будет приятным. Первый будет намного медленнее (я ожидал бы порядка величины из-за высокой накладной на чтение на пиксель), а позже медленнее (хотя и медленнее), но имеет гораздо больше связанных усилий с точки зрения перезаписи анализа данных на низком уровне данных изображения ,

Вот приблизительное руководство к тому, что вам нужно изменить на основе текущего кода:

от 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... } } 

вам нужно будет сделать примерно то же самое в других функциях. Это устраняет необходимость в Color32, class Bitmap будет иметь дело со всем, что для вас.

Bitmap.SetPixel() будет обрабатывать второй проход. Обратите внимание, что это самый простой способ переноса данных, но абсолютно не самый быстрый способ сделать это в среде среднего доверия.