2

我目前正在使用 Brendan Tompkins ImageQuantization dll。 http://codebetter.com/blogs/brendan.tompkins/archive/2007/06/14/gif-image-color-quantizer-now-with-safe-goodness.aspx

但它不能在 asp.net 中以中等信任度运行。

有谁知道在中等信任下运行的图像量化库?

更新 我不在乎解决方案是否缓慢。我只需要一些有用的东西。

4

1 回答 1

3

您应该能够使用 Marshal 替换代码,并通过 BinaryReader 之类的方式显式读取底层流。这可能会更慢,因为您必须将流完全读入您的托管内存或寻找它,而不是依赖已经在非托管内存中的副本可以快速访问,但基本上是您唯一的选择。

即使只执行读取操作,您也无法从中等信任上下文中深入研究非托管内存。

查看链接代码后,您不允许这样做是有原因的。首先,他忽略了 IntPtr 的 64/32 位方面!

他使用的底层 BitMapData 类完全基于对任意内存的不受限制的读取访问,这在中等信任下永远不会发生。
需要对他的基本功能进行重大重写,以直接使用 BitMap(使用缓慢的 GetPixel 调用)或通过传统的流 API 直接读取数据,将其放入数组中,然后自己解析出来。这些都不太可能令人愉快。前者会慢得多(由于每个像素读取的高开销,我预计会有数量级),后者的速度会更慢(尽管仍然更慢),但在重写图像数据的低级解析方面需要付出更多的努力.

以下是根据当前代码需要更改的粗略指南:

来自量化器.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 的任何需求,Bitmap 类将为您处理所有这些。

Bitmap.SetPixel()将处理第二遍。请注意,这是移植事物的最简单方法,但绝对不是在中等信任环境中进行移植的最快方法。

于 2009-07-08T18:11:25.590 回答