从 AdobeLabsUXMagicSelectionView (Adobe Creative SDK) 获取前景
Get foreground from AdobeLabsUXMagicSelectionView (Adobe Creative SDK)
我正在尝试使用 AdobeLabsUXMagicSelectionView,但我遇到了 2 个问题。我想 "cut" selected 区域(前景)使用这两种方法:
方法 1) getForeground:andMatte:
它没有给我正确的前景。当我 select 一个区域并调用 getForeground:andMatte
我给我前景和背景(混合)。
选择狗的脸
割狗脸
文档说:
Alternatively, if you don’t need to process the underlying bitmap
directly, and intend to use the results as inputs to CoreGraphics or
CoreImage, you can call:
方法 2) 在此之后,我尝试 "cut" 就像文档中那样
extension AdobeLabsUXMagicSelectionView {
func foregroundCGImage() -> CGImage {
let w = size_t(self.image.size.width)
let h = size_t(self.image.size.height)
let data = UnsafeMutablePointer<UInt8>(malloc(4 * w * h * sizeof(UInt8)))
self.readForegroundAndMatteIntoBuffer(data)
for var i = 0; i < 4 * w * h; i += 4 {
let alpha: UInt8 = UInt8(data[i + 3]) / 255
data[i] *= alpha
data[i + 1] *= alpha
data[i + 2] *= alpha
}
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.NoneSkipLast.rawValue)
let ctx = CGBitmapContextCreate(data, w, h, 8, 4 * w, CGColorSpaceCreateDeviceRGB(), bitmapInfo.rawValue)
let imageRef = CGBitmapContextCreateImage(ctx)!
return imageRef
}
}
但它只绘制(黑色)图像的非 selected 部分(背景)。
有人可以帮忙吗?我想要的是获得 selected 区域的最终图像。
更新:
正如@DonWoodward 所说,我已经创建了这个类别:
@implementation AdobeLabsUXMagicSelectionView (Foreground)
- (UIImage *)getForeground {
// show the results
// first create a UIImage of just the foreground bits per the documentation in AdobeLabsUXMagicSelectionView.h
size_t w = self.image.size.width;
size_t h = self.image.size.height;
uint8_t *data = (uint8_t *)malloc(4*w*h*sizeof(uint8_t));
[self readForegroundAndMatteIntoBuffer:data];
// Paint the non-selected portion of the image black
for (int i = 0; i < 4*w*h; i += 4) {
float alpha = (float)data[i + 3] / 255;
data[i ] *= alpha;
data[i + 1] *= alpha;
data[i + 2] *= alpha;
}
CGContextRef ctx = CGBitmapContextCreate(data, w, h, 8, 4*w, CGColorSpaceCreateDeviceRGB(), (CGBitmapInfo)kCGImageAlphaNoneSkipLast);
CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
UIImage * foregroundBits = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return foregroundBits;
}
@end
但是结果"foreground"周围有很多黑色像素。
我需要什么?获取 "clean" 前景(selected 区域,没有黑色像素)以覆盖 UIImageView
我认为问题在于您的比例因子是 uint8_t
类型,因此您将比例因子裁剪为零。使它成为一个浮动,它应该可以工作。这是来自 MagicPuppy(在 objective c 中)的代码:
// show the results
// first create a UIImage of just the foreground bits per the documentation in AdobeLabsUXMagicSelectionView.h
size_t w = _magicSelectionView.image.size.width;
size_t h = _magicSelectionView.image.size.height;
uint8_t *data = (uint8_t *)malloc(4*w*h*sizeof(uint8_t));
[_magicSelectionView readForegroundAndMatteIntoBuffer:data];
// Paint the non-selected portion of the image black
for (int i = 0; i < 4*w*h; i += 4)
{
float alpha = (float)data[i + 3] / 255;
data[i ] *= alpha;
data[i + 1] *= alpha;
data[i + 2] *= alpha;
}
CGContextRef ctx = CGBitmapContextCreate(data, w, h, 8, 4*w, CGColorSpaceCreateDeviceRGB(), (CGBitmapInfo)kCGImageAlphaNoneSkipLast);
CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
UIImage * foregroundBits = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
// show the results
_resultsView = [[UIImageView alloc] initWithFrame: CGRectMake(0, VIEW_Y_OFFSET, self.view.bounds.size.width, self.view.bounds.size.height-VIEW_Y_OFFSET)];
_resultsView.contentMode = UIViewContentModeScaleAspectFit;
[_resultsView setImage: foregroundBits];
[self.view addSubview: _resultsView];
在这种情况下,您将 RGB 通道预乘以您的 alpha 通道,这意味着您希望在创建上下文时使用 kCGImageAlphaPremultipliedLast
,如:
// Paint the non-selected portion of the image black
for (int i = 0; i < 4*w*h; i += 4)
{
float alpha = (float)data[i + 3] / 255;
data[i ] *= alpha;
data[i + 1] *= alpha;
data[i + 2] *= alpha;
}
CGContextRef ctx = CGBitmapContextCreate(data, w, h, 8, 4*w, CGColorSpaceCreateDeviceRGB(), (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
UIImage * foregroundBits = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
可以在 CGImage docs
中找到更多信息
此外,您还可以尝试将 CGImageCreateWithMask
与
的输出一起使用
- (void)getForeground:(UIImage **)foregroundImage andMatte:(UIImage **)matteImage
中所述
UIImage *fg;
UIImage *matte;
[_magicSelectionView getForeground:&fg andMatte:&matte];
CGImageRef mattedForeground = CGImageCreateWithMask(fg.CGImage, matte.CGImage);
UIImage *foregroundBits = [UIImage imageWithCGImage:mattedForeground];
// show the results
_resultsView = [[UIImageView alloc] initWithFrame: CGRectMake(0, VIEW_Y_OFFSET, self.view.bounds.size.width, self.view.bounds.size.height-VIEW_Y_OFFSET)];
_resultsView.contentMode = UIViewContentModeScaleAspectFit;
[_resultsView setImage: foregroundBits];
[self.view addSubview: _resultsView];
如果这些都不起作用,则用于呈现结果的 UIImageViews
的配置可能存在一些问题,但如果没有该代码,则很难说。
我正在尝试使用 AdobeLabsUXMagicSelectionView,但我遇到了 2 个问题。我想 "cut" selected 区域(前景)使用这两种方法:
方法 1) getForeground:andMatte:
它没有给我正确的前景。当我 select 一个区域并调用 getForeground:andMatte
我给我前景和背景(混合)。
选择狗的脸
割狗脸
文档说:
Alternatively, if you don’t need to process the underlying bitmap directly, and intend to use the results as inputs to CoreGraphics or CoreImage, you can call:
方法 2) 在此之后,我尝试 "cut" 就像文档中那样
extension AdobeLabsUXMagicSelectionView {
func foregroundCGImage() -> CGImage {
let w = size_t(self.image.size.width)
let h = size_t(self.image.size.height)
let data = UnsafeMutablePointer<UInt8>(malloc(4 * w * h * sizeof(UInt8)))
self.readForegroundAndMatteIntoBuffer(data)
for var i = 0; i < 4 * w * h; i += 4 {
let alpha: UInt8 = UInt8(data[i + 3]) / 255
data[i] *= alpha
data[i + 1] *= alpha
data[i + 2] *= alpha
}
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.NoneSkipLast.rawValue)
let ctx = CGBitmapContextCreate(data, w, h, 8, 4 * w, CGColorSpaceCreateDeviceRGB(), bitmapInfo.rawValue)
let imageRef = CGBitmapContextCreateImage(ctx)!
return imageRef
}
}
但它只绘制(黑色)图像的非 selected 部分(背景)。
有人可以帮忙吗?我想要的是获得 selected 区域的最终图像。
更新:
正如@DonWoodward 所说,我已经创建了这个类别:
@implementation AdobeLabsUXMagicSelectionView (Foreground)
- (UIImage *)getForeground {
// show the results
// first create a UIImage of just the foreground bits per the documentation in AdobeLabsUXMagicSelectionView.h
size_t w = self.image.size.width;
size_t h = self.image.size.height;
uint8_t *data = (uint8_t *)malloc(4*w*h*sizeof(uint8_t));
[self readForegroundAndMatteIntoBuffer:data];
// Paint the non-selected portion of the image black
for (int i = 0; i < 4*w*h; i += 4) {
float alpha = (float)data[i + 3] / 255;
data[i ] *= alpha;
data[i + 1] *= alpha;
data[i + 2] *= alpha;
}
CGContextRef ctx = CGBitmapContextCreate(data, w, h, 8, 4*w, CGColorSpaceCreateDeviceRGB(), (CGBitmapInfo)kCGImageAlphaNoneSkipLast);
CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
UIImage * foregroundBits = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return foregroundBits;
}
@end
但是结果"foreground"周围有很多黑色像素。
我需要什么?获取 "clean" 前景(selected 区域,没有黑色像素)以覆盖 UIImageView
我认为问题在于您的比例因子是 uint8_t
类型,因此您将比例因子裁剪为零。使它成为一个浮动,它应该可以工作。这是来自 MagicPuppy(在 objective c 中)的代码:
// show the results
// first create a UIImage of just the foreground bits per the documentation in AdobeLabsUXMagicSelectionView.h
size_t w = _magicSelectionView.image.size.width;
size_t h = _magicSelectionView.image.size.height;
uint8_t *data = (uint8_t *)malloc(4*w*h*sizeof(uint8_t));
[_magicSelectionView readForegroundAndMatteIntoBuffer:data];
// Paint the non-selected portion of the image black
for (int i = 0; i < 4*w*h; i += 4)
{
float alpha = (float)data[i + 3] / 255;
data[i ] *= alpha;
data[i + 1] *= alpha;
data[i + 2] *= alpha;
}
CGContextRef ctx = CGBitmapContextCreate(data, w, h, 8, 4*w, CGColorSpaceCreateDeviceRGB(), (CGBitmapInfo)kCGImageAlphaNoneSkipLast);
CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
UIImage * foregroundBits = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
// show the results
_resultsView = [[UIImageView alloc] initWithFrame: CGRectMake(0, VIEW_Y_OFFSET, self.view.bounds.size.width, self.view.bounds.size.height-VIEW_Y_OFFSET)];
_resultsView.contentMode = UIViewContentModeScaleAspectFit;
[_resultsView setImage: foregroundBits];
[self.view addSubview: _resultsView];
在这种情况下,您将 RGB 通道预乘以您的 alpha 通道,这意味着您希望在创建上下文时使用 kCGImageAlphaPremultipliedLast
,如:
// Paint the non-selected portion of the image black
for (int i = 0; i < 4*w*h; i += 4)
{
float alpha = (float)data[i + 3] / 255;
data[i ] *= alpha;
data[i + 1] *= alpha;
data[i + 2] *= alpha;
}
CGContextRef ctx = CGBitmapContextCreate(data, w, h, 8, 4*w, CGColorSpaceCreateDeviceRGB(), (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
UIImage * foregroundBits = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
可以在 CGImage docs
中找到更多信息此外,您还可以尝试将 CGImageCreateWithMask
与
- (void)getForeground:(UIImage **)foregroundImage andMatte:(UIImage **)matteImage
中所述
UIImage *fg;
UIImage *matte;
[_magicSelectionView getForeground:&fg andMatte:&matte];
CGImageRef mattedForeground = CGImageCreateWithMask(fg.CGImage, matte.CGImage);
UIImage *foregroundBits = [UIImage imageWithCGImage:mattedForeground];
// show the results
_resultsView = [[UIImageView alloc] initWithFrame: CGRectMake(0, VIEW_Y_OFFSET, self.view.bounds.size.width, self.view.bounds.size.height-VIEW_Y_OFFSET)];
_resultsView.contentMode = UIViewContentModeScaleAspectFit;
[_resultsView setImage: foregroundBits];
[self.view addSubview: _resultsView];
如果这些都不起作用,则用于呈现结果的 UIImageViews
的配置可能存在一些问题,但如果没有该代码,则很难说。