我正在尝试用渐变填充UIImage
。我已经实现了这个纯色。我尝试使用UIColor
colorWithPatternImage
进行填充,但它会用奇怪的颜色填充图像。有人可以指出我正确的方向。这是我用于填充洪水的方法
- (UIImage *) floodFillFromPoint:(CGPoint)startPoint withColor:(UIColor *)newColor andTolerance:(int)tolerance
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef imageRef = [self CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
unsigned char *imageData = malloc(height * width * 4);
NSUInteger bytesPerPixel = CGImageGetBitsPerPixel(imageRef) / 8;
NSUInteger bytesPerRow = CGImageGetBytesPerRow(imageRef);
NSUInteger bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
CGContextRef context = CGBitmapContextCreate(imageData,
width,
height,
bitsPerComponent,
bytesPerRow,
colorSpace,
CGImageGetBitmapInfo(imageRef));
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
//Get color at start point
unsigned int byteIndex = (bytesPerRow * startPoint.y) + startPoint.x * bytesPerPixel;
unsigned int ocolor = getColorCode(byteIndex, imageData);
//Convert newColor to RGBA value so we can save it to image.
int newRed, newGreen, newBlue, newAlpha;
const CGFloat *components = CGColorGetComponents(newColor.CGColor);
/*
If you are not getting why I use CGColorGetNumberOfComponents than read following link:
http://stackoverflow.com/questions/9238743/is-there-an-issue-with-cgcolorgetcomponents
*/
if(CGColorGetNumberOfComponents(newColor.CGColor) == 2)
{
newRed = newGreen = newBlue = components[0] * 255;
newAlpha = components[1];
}
else if (CGColorGetNumberOfComponents(newColor.CGColor) == 4)
{
newRed = components[0] * 255;
newGreen = components[1] * 255;
newBlue = components[2] * 255;
newAlpha = 255;
}
unsigned int ncolor = (newRed << 24) | (newGreen << 16) | (newBlue << 8) | newAlpha;
/*
We are using stack to store point.
Stack is implemented by LinkList.
To incress speed I have used NSMutableData insted of NSMutableArray.
To see Detail Of This implementation visit following leink.
http://iwantmyreal.name/blog/2012/09/29/a-faster-array-in-objective-c/
*/
LinkedListStack *points = [[LinkedListStack alloc] initWithCapacity:500 incrementSize:500 andMultiplier:height];
int x = startPoint.x;
int y = startPoint.y;
[points pushFrontX:x andY:y];
/*
This algorithem is prety simple though it llook odd in Objective C syntex.
To get familer with this algorithm visit following link.
http://lodev.org/cgtutor/floodfill.html
You can read hole artical for knowledge.
If you are familer with flood fill than got to Scanline Floodfill Algorithm With Stack (floodFillScanlineStack)
*/
unsigned int color;
BOOL spanLeft,spanRight;
while ([points popFront:&x andY:&y] != INVALID_NODE_CONTENT)
{
/* if (spanRight) {
newRed = newRed-1;
newBlue = newBlue+1;
}
if (spanLeft) {
newBlue = newBlue-1;
newRed = newRed+1;
}*/
byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
color = getColorCode(byteIndex, imageData);
while(y >= 0 && compareColor(ocolor, color, tolerance))
{
y--;
if(y >= 0)
{
byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
color = getColorCode(byteIndex, imageData);
}
}
y++;
spanLeft = spanRight = NO;
byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
color = getColorCode(byteIndex, imageData);
while (y < height && compareColor(ocolor, color, tolerance) )
{
// NSLog(@"compareColor");
//Change old color with newColor RGBA value
/* if (compareColor(ncolor, color, tolerance)) {
newRed = 255;
newGreen = 255;
newBlue = 255;
newAlpha = 0;
}*/
imageData[byteIndex + 0] = newRed;
imageData[byteIndex + 1] = newGreen;
imageData[byteIndex + 2] = newBlue;
imageData[byteIndex + 3] = newAlpha;
if(x > 0)
{
byteIndex = (bytesPerRow * y) + (x - 1) * bytesPerPixel;
color = getColorCode(byteIndex, imageData);
if(!spanLeft && x > 0 && compareColor(ocolor, color, tolerance))
{
[points pushFrontX:(x - 1) andY:y];
spanLeft = YES;
}
else if(spanLeft && x > 0 && !compareColor(ocolor, color, tolerance))
{
spanLeft = NO;
}
}
if(x < width - 1)
{
byteIndex = (bytesPerRow * y) + (x + 1) * bytesPerPixel;
color = getColorCode(byteIndex, imageData);
if(!spanRight && compareColor(ocolor, color, tolerance))
{
[points pushFrontX:(x + 1) andY:y];
spanRight = YES;
}
else if(spanRight && !compareColor(ocolor, color, tolerance))
{
spanRight = NO;
}
}
y++;
if(y < height)
{
byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
color = getColorCode(byteIndex, imageData);
}
}
}
//Convert Flood filled image row data back to UIImage object.
CGImageRef newCGImage = CGBitmapContextCreateImage(context);
UIImage *result = [UIImage imageWithCGImage:newCGImage];
CGImageRelease(newCGImage);
CGContextRelease(context);
free(imageData);
return result;
}
@catch (NSException *exception)
{
NSLog(@"Exception : %@", exception);
}
}
这是我用于渐变
的洪水填充filledImage = [_imageView.image floodFillFromPoint:CGPointMake((touchPoint.x*ScaleFactor)/_zoomScrollview.zoomScale,( touchPoint.y*ScaleFactor)/_zoomScrollview.zoomScale) withColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"color-book.png"]] andTolerance:5.0 ];
这是我正在使用的渐变图像:
但是显示出像这样奇怪的颜色
我正在制作一本着色书app.so它看起来应该像应用渐变后在任何着色书应用上看起来一样。 谁能告诉我问题在哪里或我该怎么做才能解决它?