К вашему сведению, я объединил ответ Керемка с моей первоначальной схемой, убрал опечатки, обобщил их, чтобы получить массив цветов, и получил все, что нужно скомпилировать. Вот результат:
+ (NSArray*)getRGBAsFromImage:(UIImage*)image atX:(int)x andY:(int)y count:(int)count
{
NSMutableArray *result = [NSMutableArray arrayWithCapacity:count];
// First get the image into your data buffer
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
// Now your rawData contains the image data in the RGBA8888 pixel format.
NSUInteger byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
for (int i = 0 ; i < count ; ++i)
{
CGFloat alpha = ((CGFloat) rawData[byteIndex + 3] ) / 255.0f;
CGFloat red = ((CGFloat) rawData[byteIndex] ) / alpha;
CGFloat green = ((CGFloat) rawData[byteIndex + 1] ) / alpha;
CGFloat blue = ((CGFloat) rawData[byteIndex + 2] ) / alpha;
byteIndex += bytesPerPixel;
UIColor *acolor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
[result addObject:acolor];
}
free(rawData);
return result;
}
getRGBAsFromImage:image atX:0 andY:0 count:image.size.width*image.size.height
Чтобы получить RGBA для последнего ряда изображения:getRGBAsFromImage:image atX:0 andY:image.size.height-1 count:image.size.width
Один из способов сделать это - нарисовать изображение в растровом контексте, который поддерживается данным буфером для данного цветового пространства (в данном случае это RGB): (обратите внимание, что это скопирует данные изображения в этот буфер, поэтому вы делаете хотите кэшировать его вместо выполнения этой операции каждый раз, когда вам нужно получить значения пикселей)
Смотрите ниже как образец:
источник
CGContextDrawImage
требует три аргумента и выше приведены только два ... Я думаю, что это должно бытьCGContextDrawImage(context, CGRectMake(0, 0, width, height), image)
Apple, технический Q & QA1509 показывает следующий простой подход:
Используйте,
CFDataGetBytePtr
чтобы получить действительные байты (и различныеCGImageGet*
методы, чтобы понять, как их интерпретировать).источник
Не могу поверить, что здесь нет ни одного правильного ответа . Нет необходимости выделять указатели, а неумноженные значения по-прежнему необходимо нормализовать. Чтобы перейти к погоне, вот правильная версия для Swift 4.
UIImage
Просто для использования.cgImage
.Причина, по которой вы должны сначала нарисовать / преобразовать изображение в буфер, заключается в том, что изображения могут иметь несколько различных форматов. Этот шаг необходим для преобразования его в согласованный формат, который вы можете прочитать.
источник
let imageObj = UIImage(named:"greencolorImg.png"); imageObj.cgImage?.colors(at: [pt1, pt2])
pt1
иpt2
являютсяCGPoint
переменными.Вот SO поток, где @Matt рендерит только нужный пиксель в контекст 1x1, смещая изображение так, чтобы нужный пиксель выравнивался с одним пикселем в контексте.
источник
источник
UIImage - это обертка, байты - CGImage или CIImage.
Согласно справочнику Apple по UIImage, объект является неизменным, и у вас нет доступа к резервным байтам. Хотя верно, что вы можете получить доступ к данным CGImage, если вы заполнили
UIImage
ихCGImage
(явным или неявным образом), они вернутся,NULL
если ониUIImage
поддерживаютсяCIImage
и наоборот.Общие приемы, чтобы обойти эту проблему
Как указано, ваши варианты
Ни один из этих приемов не очень полезен, если вы хотите выводить данные, которые не являются данными ARGB, PNG или JPEG, а данные еще не поддержаны CIImage.
Моя рекомендация, попробуйте CIImage
При разработке вашего проекта для вас может иметь больше смысла вообще избегать UIImage и выбирать что-то еще. UIImage, как оболочка изображения Obj-C, часто поддерживается CGImage до такой степени, что мы принимаем это как должное. CIImage имеет тенденцию быть лучшим форматом обертки, поскольку вы можете использовать CIContext, чтобы получить нужный формат без необходимости знать, как он был создан. В вашем случае получение растрового изображения было бы вопросом вызова
- render: toBitmap: rowBytes: bounds: format: colorSpace:
В качестве дополнительного бонуса вы можете начать делать приятные манипуляции с изображением, цепляя фильтры на изображение. Это решает множество проблем, когда изображение переворачивается вверх ногами или его необходимо повернуть / масштабировать и т. Д.
источник
Основываясь на ответе Оли и Алгала, вот обновленный ответ для Swift 3
быстрый
источник
Версия Swift 5
Ответы, приведенные здесь, являются либо устаревшими, либо неправильными, поскольку они не учитывают следующее:
image.size.width
/image.size.height
.UIView.drawHierarchy(in:afterScreenUpdates:)
метод может создавать изображения BGRA.CGImage
размер строки пикселей в байтах может быть больше, чем простое умножение ширины пикселя на 4.Приведенный ниже код должен предоставить универсальное решение Swift 5 для получения
UIColor
пикселя для всех таких особых случаев. Код оптимизирован для удобства использования и ясности, а не для производительности.источник
componentLayout
пропускаете случай, когда есть только альфа.alphaOnly
.UIImage
, что вы и сделали бы, прежде чем начать читать цвета его пикселей.Основываясь на разных ответах, но в основном на этом , это работает для того, что мне нужно:
В результате этой строки у вас будет пиксель в формате AARRGGBB с альфа-каналом, всегда установленным в FF в 4-байтовом целом числе без знака
pixel1
.источник
Для доступа к необработанным значениям RGB UIImage в Swift 5 используйте базовый CGImage и его dataProvider:
https://www.ralfebert.de/ios/examples/image-processing/uiimage-raw-pixels/
источник