Как и предполагал @Till, я реализовал алгоритм заполнения потока в очереди. Мне пришлось сделать некоторые оптимизации , чтобы сохранить потребление памяти и скорость выполнения в разумных пределах.
Я не использую алгоритм, чтобы действительно заполнить изображение. Я использую алгоритм для создания масок:
- Создать массив байтов маски (image_width * image_height bytes)
- Заполнить весь массив значениями 0xFF
- Используйте алгоритм заливки, чтобы найти все пиксели в пределах области и координаты прямоугольника, содержащего эту область.
- Для каждого найденного пикселя установить соответствующее значение в массиве байтов маски равным 0
- Создайте еще один (меньший массив) байтов маски и скопируйте часть (определяемую вычисленным прямоугольником) массива байтов маски в новый массив.
- Создать маску, используя следующий код
NSData* maskData = // construct NSData from mask bytes
CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((CFMutableDataRef)maskData);
int width = maskRight - maskLeft + 1;
int height = maskBottom - maskTop + 1;
CGImageRef maskImage = CGImageMaskCreate(width, height, 8, 8, width, dataProvider, NULL, YES);
CGDataProviderRelease(dataProvider);
- Вы можете использовать маску позже, используя код, подобный следующему
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0, 768);
CGContextScaleCTM(context, 1.0, -1.0);
CGRect r = CGRectApplyAffineTransform(maskImageRect, CGContextGetCTM(context));
CGContextClipToMask(context, r, maskImage);
CGContextTranslateCTM(context, 0.0, 768);
CGContextScaleCTM(context, 1.0, -1.0);
// mask is setup, draw here
CGContextRestoreGState(context);
Используя этот код, вы можете создать маску любой формы. Вы даже можете создать полупрозрачную маску, если хотите. Чтобы создать полупрозрачную маску, необходимо установить некоторые значения, отличные от 0, в массиве байтов маски для прозрачных областей (0 - полностью прозрачный, 255 - полностью непрозрачный).