我已经创建了一个NSImage对象,并且理想地想确定它包含的每个像素的颜色数量。这可能吗?从NSImage获取像素和颜色
6
A
回答
9
我建议创建自己的bitmap context,在graphics context包装,并设置作为当前背景下,telling the image to draw itself,然后直接访问位图背景后面的像素数据。
这将是更多的代码,但会为您节省TIFF表示以及创建数千或数百万个NSColor对象。如果您正在处理任何可观尺寸的图片,这些费用将快速增加。
6
从NSImage
获取NSBitmapImageRep
。然后你可以访问像素。
NSImage* img = ...;
NSBitmapImageRep* raw_img = [NSBitmapImageRep imageRepWithData:[img TIFFRepresentation]];
NSColor* color = [raw_img colorAtX:0 y:0];
1
在Core Image文档中查找“直方图”。
2
此代码呈现NSImage
成CGBitmapContext
:
- (void)updateImageData {
if (!_image)
return;
// Dimensions - source image determines context size
NSSize imageSize = _image.size;
NSRect imageRect = NSMakeRect(0, 0, imageSize.width, imageSize.height);
// Create a context to hold the image data
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGContextRef ctx = CGBitmapContextCreate(NULL,
imageSize.width,
imageSize.height,
8,
0,
colorSpace,
kCGImageAlphaPremultipliedLast);
// Wrap graphics context
NSGraphicsContext* gctx = [NSGraphicsContext graphicsContextWithCGContext:ctx flipped:NO];
// Make our bitmap context current and render the NSImage into it
[NSGraphicsContext setCurrentContext:gctx];
[_image drawInRect:imageRect];
// Calculate the histogram
[self computeHistogramFromBitmap:ctx];
// Clean up
[NSGraphicsContext setCurrentContext:nil];
CGContextRelease(ctx);
CGColorSpaceRelease(colorSpace);
}
给定一个位图情况下,我们可以直接访问原始图像数据,并计算直方图对于每个颜色通道:
- (void)computeHistogramFromBitmap:(CGContextRef)bitmap {
// NB: Assumes RGBA 8bpp
size_t width = CGBitmapContextGetWidth(bitmap);
size_t height = CGBitmapContextGetHeight(bitmap);
uint32_t* pixel = (uint32_t*)CGBitmapContextGetData(bitmap);
for (unsigned y = 0; y < height; y++)
{
for (unsigned x = 0; x < width; x++)
{
uint32_t rgba = *pixel;
// Extract colour components
uint8_t red = (rgba & 0x000000ff) >> 0;
uint8_t green = (rgba & 0x0000ff00) >> 8;
uint8_t blue = (rgba & 0x00ff0000) >> 16;
// Accumulate each colour
_histogram[kRedChannel][red]++;
_histogram[kGreenChannel][green]++;
_histogram[kBlueChannel][blue]++;
// Next pixel!
pixel++;
}
}
}
@end
我已经发布了一个完整的项目,一个Cocoa示例应用程序,其中包括上述。
0
使用colorAtX
与NSBitmapImageRep
并不总是导致确切正确的颜色。
我设法得到正确的颜色与这个简单的代码:
[yourImage lockFocus]; // yourImage is just your NSImage variable
NSColor *pixelColor = NSReadPixel(NSMakePoint(1, 1)); // Or another point
[yourImage unlockFocus];
相关问题
- 1. 从图像中获取像素颜色
- 2. FreeImage:获取像素颜色
- 3. GDAL获取像素颜色
- 4. Java - 获取像素颜色
- 5. 从Kinect Depth Stream获取像素颜色
- 6. 如何从像素获取颜色? OpenGL
- 7. 从CCRenderTexture获取像素的颜色
- 8. 从图片中获取像素颜色?
- 9. CMYK NSImage获取像素数据
- 10. WriteableImage - 如何获取像素的颜色?
- 11. 尝试获取像素颜色
- 12. 获取UIImage的像素颜色
- 13. Java获取像素的颜色LIVE
- 14. 使用Magick获取像素颜色++
- 15. 获取AVCaptureSession或AVCaptureVideoPreviewLayer的像素颜色
- 16. 获取rMagick中像素的颜色
- 17. 获取像素的颜色在Android的
- 18. 获取像素颜色不准确
- 19. Dart - 获取ImageElement的像素颜色
- 20. 使用调色板从TIFF获取像素颜色索引
- 21. 如何从图像中获取像素的颜色?
- 22. 从网络摄像头获取像素颜色
- 23. iOS:从图像的每个像素获取顶部颜色
- 24. 在Swift 3中使用CGPoint从图像获取像素颜色
- 25. 从Vaadin的图像获取像素颜色
- 26. Android imageview从缩放图像中获取像素颜色
- 27. 从NSProgressIndicator获取NSImage
- 28. 从CGImageRef获取NSImage
- 29. 如何获取图像中像素的颜色(加载灰色)?
- 30. 颜色有色UIImages获得像素化
这是一个非常昂贵的方法,如'colorAtX:Y:'将涉及每个像素创建'NSColor'实例,如彼得Hosey笔记。获得原始数据缓冲区并通过使用指针来计算直方图是非常有效的。 – gavinb 2010-01-03 10:28:58
嗨gavinb,你有任何方向(获取原始数据缓冲区,并通过使用指针走过)在这一个?谢谢! – RickON 2014-01-05 10:22:45
@clearlight嗯,我没有意识到我让任何人处于悬念状态。我写了一个示例应用程序,它执行上面描述的内容,并将代码添加到对此问题的答案中。我也在github上发布了它。请享用! – gavinb 2017-04-05 13:21:17