在iOS中以编程方式创建渐变图像

4

我正在尝试处理直接来自设备相机的图像数据。为了理解CGImage结构,我使用缓冲区创建图像,但这对我没有起作用(我知道不应该在Obj-C代码中使用C代码,这只是为了理解)。代码如下:

int *outBuf = malloc(sizeof(int) * width * height);
for (int i = 0; i < width * height;i ++)
{
     outBuf[i] = (((float)i) / ((float) width * height)) * 255.f;
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

CGContextRef ctx = CGBitmapContextCreate(outBuf, width, height, 8, width * 4, colorSpace, kCGImageAlphaNone);

CGImageRef img = CGBitmapContextCreateImage(ctx);
CFRelease(ref);
CGContextRelease(ctx);
free(outBuf);

CGColorSpaceRelease(colorSpace);

[view.imgView setImage: [UIImage imageWithCGImage:img]];

CGImageRelease(img);

这应该创建一个从第一个像素到最后一个像素的渐变,但结果是一个奇怪的图形:

生成的图片

这些水平间距从哪里来?(我想解决这个问题,我知道还有其他绘制渐变的可能性)提前感谢。

2个回答

3
我找到了解决方案:
我最初使用int*初始化缓冲区。每个int都有4个字节,但灰度图像每个像素只需要1个字节。将缓冲区更改为char*并修改CGBitmapContextCreate参数即可解决问题:
CGBitmapContextCreate(outBuf, width, height, 8, width, colorSpace, kCGImageAlphaNone);

enter image description here


2
有几种实现你所需的方法。以下是两个示例: 请注意,这只是为了向您展示一个示例,您应该适应参数、颜色等,以获得您想要的精确效果。希望这有所帮助。
1) 直接在绘制矩形中绘制渐变。如果您希望进行其他绘制,请在视图实现中也调用 [super drawRect:rect]。
- (void)drawRect:(CGRect)rect {
    CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
    if (CGSizeEqualToSize(self.centerOffset, CGSizeZero) == NO) {
        center.x += self.centerOffset.width;
        center.y += self.centerOffset.height;
    }

    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat components[8] = { 0.0, 0.0, 0.0, 0.5,   // Start color
                              0.0, 0.0, 0.0, 0.7 }; // End color

    CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);
    CGGradientDrawingOptions options = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
    CGFloat endRadius = [UIApplication sharedApplication].keyWindow.bounds.size.height / 2;
    CGContextDrawRadialGradient(currentContext, gradient, center, 50.0f, center, endRadius, options);

    CGGradientRelease(gradient);
    CGColorSpaceRelease(rgbColorspace); 
}

2) 使用CAGradientLayer

    UIColor *startEndColour = [UIColor redColor];
    UIColor *middleColor = [UIColor blueColor];

    NSArray *horizontalGradientColorsArray = [NSArray arrayWithObjects:(id)[startEndColour CGColor], (id)[middleColor CGColor],(id)[middleColor CGColor], (id)[startEndColour CGColor],nil];

    UIView *horizontalGradient1View = [[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, self.bounds.size.width, 1.f)];
    horizontalGradient1View.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin;
    CAGradientLayer *horizontalGradient1 = [CAGradientLayer layer];
    horizontalGradient1.frame = horizontalGradient1View.bounds;
    horizontalGradient1.colors = horizontalGradientColorsArray;
    horizontalGradient1.startPoint = CGPointMake(0, 0.5);
    horizontalGradient1.endPoint = CGPointMake(1.0, 0.5);
    [horizontalGradient1View.layer insertSublayer:horizontalGradient1 atIndex:0];
    [self addSubview:horizontalGradient1View];
    [horizontalGradient1View release];

谢谢你的回答。我知道那些可能性,但基本上我想了解为什么代码清单不起作用(我需要提到的缓冲区用于CIImage)。 - Quxflux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接