سؤال

لديّ تطبيق يسمح للمستخدم بتحديد منطقة لصورة وحفظ تلك المنطقة للملف. لقد ركضت ضد عقبة لا يمكنني الفرز. يتم تعليق الصورة النقطية التي أقوم بإنشائها لطلاء المنطقة المحددة عليها باستخدام صورة "MemoryBMP" ، ويبدو أن هذا هو ImageFormat الذي تم تعيينه لأي خلفات محملة غير مفصلة. المشكلة هي أن يتم إنشاء صورة نقطية في الذاكرة وأريد حفظه كإثبات CCITT4 Bitonal لكنني أتلقى "خطأ عام حدث في GDI+". أنا واثق جدًا من أن هذا يرجع إلى حقيقة أن Phick.Rawformat الخاصية هي تلك الذاكرة المخيفة.

يحتوي Image.save () على تحميل زائد يأخذ معلمة ImageFormat وعندما أستخدم هذا المرور ImageFormat.tiff ، فإنه يوفر جيدًا ، لكنني لا أتاح لي الفرصة لتحديد معلمات التشفير الخاصة بي.

الحل الوحيد الممكن الذي يمكنني التفكير فيه هو الحفظ للقرص باستخدام Image.save (Image ، ImageFormat) ثم إعادة تحميله (سيتم الآن تعيين Rawformat على ImageFormat.tif) ثم حفظ مرة أخرى تمرير إعدادات التشفير. هذا مجرد غبي ، يجب أن يكون هناك طريقة أفضل.

فيما يلي عملية قص من التعليمات البرمجية (هذا مجرد اختبار أشياء) يجب أن تعطيك فكرة عما أفعله في حالة عدم توصيل وصفاتي السابقة بما فيه الكفاية:

SizeF dpiScale = GetScreenToImageDPIRatio(loadedImage);
using (Bitmap image = new Bitmap(loadedImage,
    (int)(_cropBox.Width * dpiScale.Width),
    (int)(_cropBox.Height * dpiScale.Height)))
{
    image.SetResolution(loadedImage.HorizontalResolution, 
        loadedImage.VerticalResolution);

    using (Graphics g = Graphics.FromImage(image))
    {
        g.DrawImage(loadedImage, 0, 0, new Rectangle(
            (int)(_cropBox.Location.X * dpiScale.Width),
            (int)(_cropBox.Location.Y * dpiScale.Height),
            (int)(_cropBox.Width * dpiScale.Width),
            (int)(_cropBox.Height * dpiScale.Height)),
            GraphicsUnit.Pixel);
    }

    //  It's stuck as a MemoryBmp so none of these checks will work
    if (true || image.RawFormat.Equals(ImageFormat.Tiff))
    {
        ImageCodecInfo tiffCodecInfo = ImageUtils.GetEncoderInfo("image/tiff");
        EncoderParameters myEncoderParameters = new EncoderParameters(2);

        myEncoderParameters.Param[0] = new
            EncoderParameter(System.Drawing.Imaging.Encoder.Compression,
                (long)EncoderValue.CompressionCCITT4);
        myEncoderParameters.Param[1] = new
            EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 1L);

        image.Save(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".tif"),
            tiffCodecInfo, myEncoderParameters);

        //  The file is a "MemoryBmp" and it's screwing things up
        //image.Save(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".tif"),
        //    ImageFormat.Tiff);
    }
    else
    {
        //  other format saving support, blah blah blah
    }
}

أوه ، أود أن أذكر أن "LoadedIimage" هي في الواقع صورة TIFF ، لقد مررت بالإشارة إلى loadedImage إلى bitmap.ctor () لمعرفة ما إذا كان ذلك سيؤدي إلى ما يتعامل معه ولكنه لم يحدث فرقًا.

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

المحلول

اكتشف أن CCITT4 لا يتطلب صورًا ثنائية التونال ، ها! لذلك خرجت من Googling وصادفت مقالة codeproject وتجول حول المصدر. قدم المؤلف طريقة لائقة جميلة لتحويل 32bppargb إلى 1bpp bi-onal. لقد جربتها وهي سريعة (عرض اختبار حوالي 34 مللي ثانية لصفحة واحدة) وقد فعلت الخدعة!

أنا أجيب على سؤالي. آمل أن يساعد هذا على الأقل شخصًا آخر يصادف هذه المشكلة.

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