回答
这里是我的结果,这工作得很好。
NSImage中+ OpenCV.h:
//
// NSImage+OpenCV.h
//
#import <AppKit/AppKit.h>
@interface NSImage (NSImage_OpenCV) {
}
+(NSImage*)imageWithCVMat:(const cv::Mat&)cvMat;
-(id)initWithCVMat:(const cv::Mat&)cvMat;
@property(nonatomic, readonly) cv::Mat CVMat;
@property(nonatomic, readonly) cv::Mat CVGrayscaleMat;
@end
NSImage中+ OpenCV.mm:
//
// NSImage+OpenCV.mm
//
#import "NSImage+OpenCV.h"
static void ProviderReleaseDataNOP(void *info, const void *data, size_t size)
{
return;
}
@implementation NSImage (NSImage_OpenCV)
-(CGImageRef)CGImage
{
CGContextRef bitmapCtx = CGBitmapContextCreate(NULL/*data - pass NULL to let CG allocate the memory*/,
[self size].width,
[self size].height,
8 /*bitsPerComponent*/,
0 /*bytesPerRow - CG will calculate it for you if it's allocating the data. This might get padded out a bit for better alignment*/,
[[NSColorSpace genericRGBColorSpace] CGColorSpace],
kCGBitmapByteOrder32Host|kCGImageAlphaPremultipliedFirst);
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:bitmapCtx flipped:NO]];
[self drawInRect:NSMakeRect(0,0, [self size].width, [self size].height) fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
[NSGraphicsContext restoreGraphicsState];
CGImageRef cgImage = CGBitmapContextCreateImage(bitmapCtx);
CGContextRelease(bitmapCtx);
return cgImage;
}
-(cv::Mat)CVMat
{
CGImageRef imageRef = [self CGImage];
CGColorSpaceRef colorSpace = CGImageGetColorSpace(imageRef);
CGFloat cols = self.size.width;
CGFloat rows = self.size.height;
cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels
CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to backing data
cols, // Width of bitmap
rows, // Height of bitmap
8, // Bits per component
cvMat.step[0], // Bytes per row
colorSpace, // Colorspace
kCGImageAlphaNoneSkipLast |
kCGBitmapByteOrderDefault); // Bitmap info flags
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), imageRef);
CGContextRelease(contextRef);
CGImageRelease(imageRef);
return cvMat;
}
-(cv::Mat)CVGrayscaleMat
{
CGImageRef imageRef = [self CGImage];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGFloat cols = self.size.width;
CGFloat rows = self.size.height;
cv::Mat cvMat = cv::Mat(rows, cols, CV_8UC1); // 8 bits per component, 1 channel
CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to backing data
cols, // Width of bitmap
rows, // Height of bitmap
8, // Bits per component
cvMat.step[0], // Bytes per row
colorSpace, // Colorspace
kCGImageAlphaNone |
kCGBitmapByteOrderDefault); // Bitmap info flags
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), imageRef);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);
CGImageRelease(imageRef);
return cvMat;
}
+ (NSImage *)imageWithCVMat:(const cv::Mat&)cvMat
{
return [[[NSImage alloc] initWithCVMat:cvMat] autorelease];
}
- (id)initWithCVMat:(const cv::Mat&)cvMat
{
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()];
CGColorSpaceRef colorSpace;
if (cvMat.elemSize() == 1)
{
colorSpace = CGColorSpaceCreateDeviceGray();
}
else
{
colorSpace = CGColorSpaceCreateDeviceRGB();
}
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
CGImageRef imageRef = CGImageCreate(cvMat.cols, // Width
cvMat.rows, // Height
8, // Bits per component
8 * cvMat.elemSize(), // Bits per pixel
cvMat.step[0], // Bytes per row
colorSpace, // Colorspace
kCGImageAlphaNone | kCGBitmapByteOrderDefault, // Bitmap info flags
provider, // CGDataProviderRef
NULL, // Decode
false, // Should interpolate
kCGRenderingIntentDefault); // Intent
NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage:imageRef];
NSImage *image = [[NSImage alloc] init];
[image addRepresentation:bitmapRep];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return image;
}
@end
用法示例:
只需导入这样的:
#import "NSImage+OpenCV.h"
而且使用这样的:
cv::Mat cvMat_test;
NSImage *image = [NSImage imageNamed:@"test.jpg"];
cvMat_test = [image CVMat];
[myImageView setImage:[NSImage imageWithCVMat:cvMat_test]];
+1 Super。谢谢(你的)信息。 – karlphillip 2011-12-19 19:03:57
有一些内存泄漏。需要释放[self CGImage],将其设置为一个变量,然后释放CVmat和CVGrayscaleMat中的CGContextDrawImage。 CGImageRef imageRef = [self CGImage]; ... CGImageRelease(imageRef); – 2012-01-11 17:41:39
@PaulSolt感谢您的信息!修正了:) – dom 2012-01-12 13:26:59
在 - (ID)initWithCVMat:(常量CV ::垫&)CvMat中,你不应该被加入表示自我,而不是新NSImage中?
-(id)initWithCVMat:(const cv::Mat *)iMat
{
if(self = [super init]) {
NSData *tData = [NSData dataWithBytes:iMat->data length:iMat->elemSize() * iMat->total()];
CGColorSpaceRef tColorSpace;
if(iMat->elemSize() == 1) {
tColorSpace = CGColorSpaceCreateDeviceGray();
} else {
tColorSpace = CGColorSpaceCreateDeviceRGB();
}
CGDataProviderRef tProvider = CGDataProviderCreateWithCFData((CFDataRef) tData);
CGImageRef tImage = CGImageCreate(
iMat->cols,
iMat->rows,
8,
8 * iMat->elemSize(),
iMat->step[0],
tColorSpace,
kCGImageAlphaNone | kCGBitmapByteOrderDefault,
tProvider,
NULL,
false,
kCGRenderingIntentDefault);
NSBitmapImageRep *tBitmap = [[NSBitmapImageRep alloc] initWithCGImage:tImage];
[self addRepresentation:tBitmap];
[tBitmap release];
CGImageRelease(tImage);
CGDataProviderRelease(tProvider);
CGColorSpaceRelease(tColorSpace);
}
return self;
}
- 1. 将数据从cv :: Mat复制到CvMat并反之亦然
- 2. 转换为&从OpenCV cv :: Mat,NSImage
- 3. cv :: Mat aaa()之间的区别和cv :: Mat aaa = cv :: Mat();
- 4. C++ OpenCV:将mat转换为base64,反之亦然
- 5. 如何将int []转换为OpenCV Mat? (反之亦然)
- 6. hadoop mapreduce反之亦然
- 7. boost :: shared_ptr void *反之亦然
- 8. XAML到Html,反之亦然
- 9. 长[]要长[],反之亦然?
- 10. PHP到C#反之亦然
- 11. 流程图到JSON和反之亦然
- 12. 反之亦然在MySQL查询子句
- 13. Comunicate的NodeJS与PHP,反之亦然
- 14. java.sql.Timestamp到Joda立即反之亦然
- 15. php编码字符串,反之亦然
- 16. 转换位图的ByteArray反之亦然
- 17. 从Python调用Jython(或反之亦然)
- 18. 上一个复选框,反之亦然
- 19. 将列转换成行,反之亦然
- 20. DeflateStream/GZipStream到CryptoStream的,反之亦然
- 21. 演员吨至BOOL和反之亦然
- 22. mongodb的组值反之亦然
- 23. 铸造SOMETYPE **到SOMETYPE * [],反之亦然
- 24. 有关博客文章,反之亦然
- 25. NSArray的以描述,反之亦然
- 26. 填充JSON到C#类,反之亦然
- 27. Hankaku与Zenkaku,反之亦然在Java中
- 28. wxSlider更新wxTextCtrl反之亦然
- 29. 从MinGW使用msysGit,反之亦然
- 30. TFS到GitHub和反之亦然同步
这真的很有帮助,但这不是实现它的方法。你需要调整你的材料到Q&A格式,所以先问问题然后回答。 – karlphillip 2011-12-19 18:52:52
啊,好的。编辑我的第一篇文章,并用我的解决方案回答:) – dom 2011-12-19 18:56:32