Pergunta

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

Mas não é executado no confiança média em asp.net.

Alguém sabe de uma biblioteca de quantização de imagem que é executado em meio confiança?

Atualizar Eu não me importo se a solução é lento. Eu só preciso de algo que funciona.

Foi útil?

Solução

Você deve ser capaz de substituir o código usando Marshal com a leitura explícita do fluxo subjacente através de algo como BinaryReader. Isso pode ser mais lento desde que você deve ler o fluxo inteiramente em sua memória gerenciada ou procurar para ele em vez de confiar na cópia já na memória não gerenciada sendo rapidamente acessível, mas é fundamentalmente a sua única opção.

Você simplesmente não pode ir espeleologia na memória não gerenciado a partir de um contexto de confiança média, mesmo que apenas realizar operações de leitura.

Tendo olhei para o código ligado há uma razão que você não está autorizado a fazer esse tipo de coisa. Para começar ele está ignorando o aspecto 64 / 32bit da IntPtr!

A classe BitmapData subjacente ele está usando é totalmente baseada em ter acesso de leitura irrestrito a memória arbitrária, isso nunca aconteça sob confiança média.
Uma reescrita significativa da sua funcionalidade de base será necessário para um ou outro BitMap utilização é directamente (com as chamadas GetPixel lento) ou ler os dados directamente através apis de transmissão convencionais, deixá-la cair em uma matriz (s) e, em seguida, analisá-lo para si mesmo. Nenhum destes são susceptíveis de ser agradável. O primeiro vai ser muito mais lento (eu esperaria ordem de magnitude, devido à alta sobrecarga por leitura pixel), o mais tarde, menos lento (embora ainda mais lento), mas tem muito mais associado esforço em termos de reescrever a análise de baixo nível dos dados de imagem .

Aqui está um guia para o que você precisa mudar de acordo com o código atual:

a partir 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...
    }
}

Você precisa fazer mais ou menos o mesmo nas outras funções. Isso elimina qualquer necessidade de Color32, a classe Bitmap vai lidar com tudo isso para você.

Bitmap.SetPixel() vai lidar com a segunda passagem. Note-se que esta é a maneira mais fácil de coisas portuárias, mas absolutamente não é a maneira mais rápida de fazê-lo dentro de um ambiente de confiança média.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top