Получить передний план из AdobeLabsUXMagicSelectionView (Adobe Creative SDK)

Я пытаюсь использовать AdobeLabsUXMagicSelectionView, и я сталкиваюсь с с 2 проблемами. Я хочу «вырезать» выделенную область (передний план) двумя способами:

Метод 1) getForeground:andMatte: Это не дает мне правильного переднего плана. Когда я выбираю область и вызываю getForeground:andMatte, я даю передний план и фон (смешанный).

Выбор морды собаки  введите описание изображения здесь

Стрижка морды собаки  введите описание изображения здесь

В документации говорится:

В качестве альтернативы, если вам не нужно напрямую обрабатывать базовое растровое изображение и вы собираетесь использовать результаты в качестве входных данных для CoreGraphics или CoreImage, вы можете вызвать:

Способ 2) После этого пытаюсь "вырезать" как это делает документация

extension AdobeLabsUXMagicSelectionView {

    func foregroundCGImage() -> CGImage {
        let w = size_t(self.image.size.width)
        let h = size_t(self.image.size.height)
        let data = UnsafeMutablePointer<UInt8>(malloc(4 * w * h * sizeof(UInt8)))
        self.readForegroundAndMatteIntoBuffer(data)

        for var i = 0; i < 4 * w * h; i += 4 {
            let alpha: UInt8 = UInt8(data[i + 3]) / 255
            data[i] *= alpha
            data[i + 1] *= alpha
            data[i + 2] *= alpha
        }

        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.NoneSkipLast.rawValue)
        let ctx = CGBitmapContextCreate(data, w, h, 8, 4 * w, CGColorSpaceCreateDeviceRGB(), bitmapInfo.rawValue)
        let imageRef = CGBitmapContextCreateImage(ctx)!

        return imageRef
    }

}

Но он закрашивает (черным) только невыделенную часть (фон) изображения.

Кто-нибудь может помочь? Я хочу получить окончательное изображение выбранной области.

ОБНОВЛЕНИЕ:

Как сказал @DonWoodward, я создал эту категорию:

@implementation AdobeLabsUXMagicSelectionView (Foreground)

- (UIImage *)getForeground {
    // show the results
    // first create a UIImage of just the foreground bits per the documentation in AdobeLabsUXMagicSelectionView.h
    size_t w = self.image.size.width;
    size_t h = self.image.size.height;

    uint8_t *data = (uint8_t *)malloc(4*w*h*sizeof(uint8_t));
    [self readForegroundAndMatteIntoBuffer:data];

    // Paint the non-selected portion of the image black
    for (int i = 0; i < 4*w*h; i += 4) {
        float alpha = (float)data[i + 3] / 255;
        data[i    ] *= alpha;
        data[i + 1] *= alpha;
        data[i + 2] *= alpha;
    }
    CGContextRef ctx = CGBitmapContextCreate(data, w, h, 8, 4*w, CGColorSpaceCreateDeviceRGB(), (CGBitmapInfo)kCGImageAlphaNoneSkipLast);
    CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
    UIImage * foregroundBits = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);

    return foregroundBits;
}

@end

Но в результате получается много черных пикселей вокруг «переднего плана».

введите здесь описание изображения  введите описание изображения здесь

Что мне нужно? Получите "чистый" передний план (выделенную область без черных пикселей), чтобы поместить его поверх UIImageView


person Klevison    schedule 27.01.2016    source источник


Ответы (2)


В этом случае вы предварительно умножаете каналы RGB на ваш альфа-канал, что подразумевает, что вы хотите использовать kCGImageAlphaPremultipliedLast при создании своего контекста, как в:

// Paint the non-selected portion of the image black
for (int i = 0; i < 4*w*h; i += 4)
{
    float alpha = (float)data[i + 3] / 255;
    data[i    ] *= alpha;
    data[i + 1] *= alpha;
    data[i + 2] *= alpha;
}
CGContextRef ctx = CGBitmapContextCreate(data, w, h, 8, 4*w, CGColorSpaceCreateDeviceRGB(), (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
UIImage * foregroundBits = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);

Дополнительную информацию можно найти в документы CGImage

Кроме того, вы также можете попробовать использовать CGImageCreateWithMask с выводом

- (void)getForeground:(UIImage **)foregroundImage andMatte:(UIImage **)matteImage

как описано в Руководство по программированию Quartz 2D

UIImage *fg;
UIImage *matte;

[_magicSelectionView getForeground:&fg andMatte:&matte];

CGImageRef mattedForeground = CGImageCreateWithMask(fg.CGImage, matte.CGImage);
UIImage *foregroundBits = [UIImage imageWithCGImage:mattedForeground];

// show the results
_resultsView = [[UIImageView alloc] initWithFrame: CGRectMake(0, VIEW_Y_OFFSET, self.view.bounds.size.width, self.view.bounds.size.height-VIEW_Y_OFFSET)];
_resultsView.contentMode = UIViewContentModeScaleAspectFit;
[_resultsView setImage: foregroundBits];
[self.view addSubview: _resultsView];

Если ни одно из этих действий не работает, возможно, есть проблемы с конфигурацией UIImageViews, используемого для рендеринга результатов, но без этого кода трудно сказать.

person lobudge    schedule 17.03.2016

Я думаю, проблема в том, что ваш масштабный коэффициент имеет тип uint8_t, и поэтому вы обрезаете масштабный коэффициент до нуля. Сделайте это поплавком, и он должен работать. Вот код MagicPuppy (в объекте c), который это делает:

    // show the results
    // first create a UIImage of just the foreground bits per the documentation in AdobeLabsUXMagicSelectionView.h
    size_t w = _magicSelectionView.image.size.width;
    size_t h = _magicSelectionView.image.size.height;

    uint8_t *data = (uint8_t *)malloc(4*w*h*sizeof(uint8_t));
    [_magicSelectionView readForegroundAndMatteIntoBuffer:data];

    // Paint the non-selected portion of the image black
    for (int i = 0; i < 4*w*h; i += 4)
    {
        float alpha = (float)data[i + 3] / 255;
        data[i    ] *= alpha;
        data[i + 1] *= alpha;
        data[i + 2] *= alpha;
    }
    CGContextRef ctx = CGBitmapContextCreate(data, w, h, 8, 4*w, CGColorSpaceCreateDeviceRGB(), (CGBitmapInfo)kCGImageAlphaNoneSkipLast);
    CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
    UIImage * foregroundBits = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);

    // show the results
    _resultsView = [[UIImageView alloc] initWithFrame: CGRectMake(0, VIEW_Y_OFFSET, self.view.bounds.size.width, self.view.bounds.size.height-VIEW_Y_OFFSET)];
    _resultsView.contentMode = UIViewContentModeScaleAspectFit;
    [_resultsView setImage: foregroundBits];
    [self.view addSubview: _resultsView];
person Don Woodward    schedule 02.02.2016