2014-11-02 2 views
2

У меня есть слой, где я хочу, чтобы пользователь рисовал «маску» для вырезания изображений. Это полупрозрачно, чтобы они могли видеть под тем, что они выбирают.Как удалить непрозрачность, но сохранить альфа-канал UIImage?

Как я могу обработать это так, чтобы данные чертежа имели альфа 1.0, но сохраняли альфа-канал (для маскировки)?

TL: DR - Я хочу, чтобы черная область была сплошной, одного цвета.

  • Здесь желаемая до и после (белый фон должен быть прозрачным в обоих): Desired Before & After

что-то вроде этого:

for (pixel in image) { 
    if (pixel.alpha != 0.0) { 
    fill solid black 
    } 
} 

ответ

2

Ниже следует делать то, что вы» повторно после. Большинство кода от How to set the opacity/alpha of a UIImage? Я только добавил тест для значения альфа, прежде чем преобразовать цвет пикселя в черный.

// Create a pixel buffer in an easy to use format 
CGImageRef imageRef = [[UIImage imageNamed:@"testImage"] CGImage]; 
NSUInteger width = CGImageGetWidth(imageRef); 
NSUInteger height = CGImageGetHeight(imageRef); 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

UInt8 * m_PixelBuf = malloc(sizeof(UInt8) * height * width * 4); 

NSUInteger bytesPerPixel = 4; 
NSUInteger bytesPerRow = bytesPerPixel * width; 
NSUInteger bitsPerComponent = 8; 
CGContextRef context = CGBitmapContextCreate(m_PixelBuf, width, height, 
              bitsPerComponent, bytesPerRow, colorSpace, 
              kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 
CGContextRelease(context); 

//alter the alpha when the alpha of the source != 0 
int length = height * width * 4; 
for (int i=0; i<length; i+=4) { 
    if (m_PixelBuf[i+3] != 0) { 
    m_PixelBuf[i+3] = 255; 
    } 
} 

//create a new image 
CGContextRef ctx = CGBitmapContextCreate(m_PixelBuf, width, height, 
             bitsPerComponent, bytesPerRow, colorSpace, 
             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

CGImageRef newImgRef = CGBitmapContextCreateImage(ctx); 
CGColorSpaceRelease(colorSpace); 
CGContextRelease(ctx); 
free(m_PixelBuf); 

UIImage *finalImage = [UIImage imageWithCGImage:newImgRef]; 
CGImageRelease(newImgRef); 

finalImage теперь будет содержать изображение, где все пиксели, которые не имеют альфа 0,0 имеют альфа 1.

+0

приятный, просто нужна небольшая настройка, чтобы пиксели были черными: 'for (int i = 0; i Halpo

+0

При всем моем уважении я не думаю, что этот метод настройки пиксельного буфера исходного растрового изображения является правильным подходом. Это предполагает, что альфа-канал отражает просто непрозрачность линии. Но ваш обработанный путь может иметь сглаженные края; эта техника будет излишне вводить в маску зубцы. Я бы посоветовал не редактировать этот буфер пикселей. Вместо этого вы хотите повторно отобразить исходные пути вашей модели, используя альфа 1.0. Таким образом, ваша маска будет наслаждаться сглаженной природой краев, делая основной путь хода полностью непрозрачным. – Rob

1

базовая модель для этого приложения не должно быть изображения. Это не вопрос «как мне создать одно изображение изображения из другого».

Вместо этого базовая объектная модель должна быть массивом путей. Затем, когда вы хотите создать изображение с прозрачными путями против непрозрачных путей, это просто вопрос о том, как вы создаете этот массив путей. Как только вы решаете его таким образом, проблема не является сложным вопросом манипулирования изображениями, а просто вопросом рендеринга.

Кстати, мне очень нравится эта модель массива путей, потому что тогда становится довольно тривиально делать такие вещи, как «gee, позвольте мне предоставить функцию отмены, позволяя пользователю удалять по одному штриху за раз». Это открывает вам всевозможные функциональные улучшения.

Что касается особенностей визуализации этих путей, он может быть реализован различными способами. Вы можете использовать пользовательскую функцию drawRect для подкласса UIView, который отображает пути с соответствующей альфой. Или вы можете сделать это с помощью CAShapeLayer объектов. Или вы можете сделать несколько гибридов (создание новых снимков изображений при завершении добавления каждого пути, что избавит вас от необходимости повторно отображать все пути каждый раз). Существует множество способов решения этой проблемы.

Но главное понимание заключается в использовании в базовую модель массива путей, а затем рендеринга двух ваших типов изображений становится довольно тривиальной задачей:

pathsmask

Первое изображение является рендеринг пучка путей как CAShapeLayer объектов с alpha из 0,5. Второй - тот же рендеринг, но с alpha 1.0. Опять же, не имеет значения, используете ли вы слои формы или низкоуровневые вызовы Core Graphics, но основная идея такая же. Либо сделайте свои пути полупрозрачностью, либо нет.

+0

мое приложение использует пути (с возможностью отмены и т. Д.), Это только для окончательного решения рендеринга – Halpo

+0

Тогда я не понимаю вопроса. Проведите дважды два пути, чтобы получить два изображения, один раз с альфами меньше одного, а затем снова с альфами, равными единице. Это дает вам два изображения. – Rob