В настоящее время я использую dll DLL для Brendan Tompkins ImageQuantization. http://codebetter.com/blogs/brendan.tompkins/archive/2007/06/14/gif-image-color-quantizer-now-with-safe-goodness.aspx
Но он не работает в средстве доверия в asp.net.
Кто-нибудь знает о библиотеке квантования изображения, которая работает в среде доверия?
Обновление Меня не волнует, медленно ли решение. Мне просто нужно что-то, что работает.
Вы должны иметь возможность заменить код с помощью маршала явным чтением базового потока через что-то вроде BinaryReader. Это может быть медленнее, так как вы должны полностью прочитать поток в своей управляемой памяти или искать в нем, а не полагаться на то, что копия, уже находящаяся в неуправляемой памяти, быстро доступна, но в принципе является вашим единственным вариантом.
Вы просто не можете перейти в неуправляемую память из контекста среднего доверия, даже если выполняете только операции чтения.
Посмотрев на связанный код, есть причина, по которой вам не разрешают делать подобные вещи. Для начала он проигнорировал 64/32-битный аспект IntPtr!
Базовый класс BitMapData, который он использует, полностью основан на свободном доступе чтения к произвольной памяти, это никогда не происходит под средним доверием. Значительная переработка его базовой функциональности потребует либо напрямую использовать BitMap (с медленными вызовами GetPixel), либо читать данные напрямую через обычный поток 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 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, класс Bitmap будет иметь дело со всем, что для вас.
Bitmap.SetPixel()
будет иметь дело со вторым проходом. Обратите внимание, что это самый простой способ переносить вещи, но совсем не самый быстрый способ сделать это в среде среднего доверия.