هل هناك أي طريقة للقيام بتجميل الصورة بأمان ومع عدم وجود حشد؟

StackOverflow https://stackoverflow.com/questions/1099655

سؤال

أنا حاليا باستخدام 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.

هل يعرف أحد بمكتبة قياس الصورة التي تعمل في الثقة المتوسطة؟

تحديثلا يهمني إذا كان الحل بطيئا. أنا فقط بحاجة إلى شيء يعمل.

هل كانت مفيدة؟

المحلول

يجب أن تكون قادرا على استبدال التعليمات البرمجية باستخدام Marshal مع قراءة صريحة للدفق الأساسي عبر شيء مثل BinaryReader. قد يكون هذا أبطأ لأنه يجب عليك قراءة الدفق بالكامل في ذاكرتك المدارة أو البحث فيه بدلا من الاعتماد على النسخة الموجودة بالفعل في الذاكرة غير المدارة التي يمكن الوصول إليها بسرعة ولكنها خيارك الوحيد بشكل أساسي.

لا يمكنك ببساطة أن تذهب إلى ذاكرة غير مدارة من سياق ثقة متوسطة، حتى لو أداء عمليات القراءة فقط.

بعد أن نظرت إلى التعليمات البرمجية المرتبطة هناك سبب لا يسمح لك بذلك هذا النوع من الأشياء. بالنسبة للمبتدئين، يتجاهل الجانب 64/32bit من Intptr!

يتم استخدام فئة Bitmapdata الأساسية التي يستخدمها تماما على وجود الوصول القراءة غير المقيد إلى الذاكرة التعسفية، وهذا لا يحدث أبدا تحت الثقة المتوسطة.
ستكون هناك حاجة إلى إعادة كتابة مهم من وظائفه الأساسية إما استخدام النقطات النقطية مباشرة (مع مكالمات GetPixel البطيئة) أو اقرأ البيانات مباشرة عبر واجهات برمجة التطبيقات المتدفقة التقليدية، مما يسقطها في صفيف (صفيف) ثم تحليلها بنفسك. لا من المرجح أن يكون أي من هذه اللطيفة. السابق سيكون أبطأا بكثير (كنت أتوقع ترتيب من الدرجة الأولى بسبب ارتفاع النفقات العامة لكل بكسل)، في وقت لاحق أقل بطيئة (على الرغم من أنها لا تزال أبطأ) ولكن لديها المزيد من الجهد المرتبط بكثير من حيث إعادة كتابة التحليل المنخفض المستوى من بيانات الصورة وبعد

إليك دليل تقريبي لما تحتاج إلى تغييره بناء على الرمز الحالي:

من الكم.cs.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.SetPixel() سوف تتعامل مع المرور الثاني. لاحظ أن هذه هي أسهل طريقة لأشياء الميناء ولكنها ليست على الإطلاق أسرع طريقة للقيام بذلك داخل بيئة ثقة متوسطة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top