Конвертировать 24-битное изображение в 8-битное в одно касание?

У нас есть приложение для обработки изображений, в котором мы используем ведущие инструменты для конвертации изображений из 24/48 бит в 8 бит.

В качестве эксперимента я портирую приложение на iPad с помощью MonoTouch и C#, теперь компоненты LeadTools несовместимы с Monotouch. Есть ли альтернатива, которую я могу использовать? если нет, то как я могу конвертировать 24/48 битные изображения в 8 бит?

2 ответа

Решение

Чтобы использовать инструменты обработки изображений Apple, вот где я бы начал:

  1. Преобразуйте ваши необработанные байты в формат пикселей, поддерживаемый платформой. См. Документацию Quartz 2D о поддерживаемых форматах пикселей.
    Обратите внимание, что iOS в настоящее время не имеет 24- или 48-битного формата. Однако, если ваш 24-битный формат равен 8 битам на канал (RGB), вы можете добавить 8 бит игнорируемой альфы. (Альфа-опции находятся в MonoTouch.CoreGraphics.CGImageAlphaInfo)

  2. Конвертируйте ваши необработанные байты в CGImage. Вот пример того, как это сделать

        var provider = new CGDataProvider(bytes, 0, bytes.Length);
        int bitsPerComponent = 8;
        int components = 4;
        int height = bytes.Length / components / width;
        int bitsPerPixel = components * bitsPerComponent;
        int bytesPerRow = components * width;   // Tip:  When you create a bitmap graphics context, you’ll get the best performance if you make sure the data and bytesPerRow are 16-byte aligned.
        bool shouldInterpolate = false;
        var colorSpace = CGColorSpace.CreateDeviceRGB();
        var cgImage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, 
                                  colorSpace, CGImageAlphaInfo.Last, provider,
                                  null, shouldInterpolate, CGColorRenderingIntent.Default);
    
  3. Используйте Core Image Filter для преобразования в монохромный

        var mono = new CIColorMonochrome
        {
            Color = CIColor.FromRgb(1, 1, 1),
            Intensity = 1.0f,
            Image = CIImage.FromCGImage(image)
        };
        CIImage output = mono.OutputImage;
        var context = CIContext.FromOptions(null);
        var renderedImage = context.CreateCGImage(output, output.Extent);
    
  4. Наконец, вы можете получить необработанные байты этого изображения, рисуя в CGBitmapContext, сконструированный в соответствии с вашими желаемыми параметрами.

Я подозреваю, что этот конвейер может быть оптимизирован, но это место для начала. Мне было бы интересно услышать, чем вы в конечном итоге.

Я думаю, что ваш лучший вариант будет делать нативные вызовы библиотек LeadTools - любая манипуляция изображениями в C#, о которой я могу подумать, будет опираться на такие компоненты, как GDI+ и пространство имен System.Drawing, которое не поддерживается monotouch.

Вы можете вызвать собственный код Objective-C из своего проекта с одним прикосновением, создав проект Binding - http://docs.xamarin.com/ios/advanced_topics/binding_objective-c_types

Это должно позволить вам портировать ваш код таким образом, чтобы он получал точно такое же изображение / качество / формат без необходимости переделки вашего текущего кода преобразования.

Другие вопросы по тегам