Проблема с рисованием на UIImage

Я использую следующий код для рисования поверх изображения. Все сенсорные делегаты работают, но рисунок не отображается поверх UIImage. Вот код. Я не могу определить проблему. Заранее спасибо.

- (id)initWithCoder:(NSCoder *)aDecoder {

    if ((self = [super initWithCoder:aDecoder])) {
        [self setupVariables];
    }

    return self;
}

- (void)drawPic:(UIImage *)thisPic {    
    myPic = thisPic;

    [myPic retain];
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect {

    float newHeight;
    float newWidth;
    float xPos;
    float yPos;
    float ratio;

    if (myPic != NULL) {
        ratio = myPic.size.height/460;

        if (myPic.size.width/320 > ratio) {
            ratio = myPic.size.width/320;
        }

        newHeight = myPic.size.height/ratio;
        newWidth = myPic.size.width/ratio;

        xPos = (320 - newWidth) / 2;
        yPos = (460 - newHeight) / 2;

        [myPic drawInRect:CGRectMake(xPos, yPos, newWidth, newHeight)];
    }
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

    NSArray *allTouches = [[event allTouches] allObjects];

    if ([allTouches count] > 1) {
        return;
    }
    else {
        [self drawPoint:[allTouches objectAtIndex:0]];
    }    
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    NSArray *allTouches = [[event allTouches] allObjects];

    if ([allTouches count] > 1) {
        return;
    }
    else {
        [self drawPoint:[allTouches objectAtIndex:0]];

        self.previousPoint = nil;
        self.point = nil;
    }    
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {

    NSArray *allTouches = [[event allTouches] allObjects];

    if ([allTouches count] > 1) {
        return;
    }
    else {
        [self drawPoint:[allTouches objectAtIndex:0]];

        self.previousPoint = nil;
        self.point = nil;
    }        
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    NSArray *allTouches = [[event allTouches] allObjects];

    if ([allTouches count] > 1) {
        return;
    }
    else {
        [self drawPoint:[allTouches objectAtIndex:0]];
    }    
}


- (void)dealloc {

    CGContextRelease(offScreenBuffer);
    [point release];
    [previousPoint release];
    [super dealloc];
}

- (void)setupVariables {

    self.point = nil;
    self.previousPoint = nil;
    offScreenBuffer = [self setupBuffer];
}

- (CGContextRef)setupBuffer {

    CGSize size = self.bounds.size;

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef context =  CGBitmapContextCreate(NULL,size.width,size.height,8,size.width*4, colorSpace,kCGImageAlphaPremultipliedLast);

    CGColorSpaceRelease(colorSpace);

    CGContextTranslateCTM(context, 0, size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    return context;    
}

- (void)drawToBuffer {

    //                  Red  Gr   Blu  Alpha
    CGFloat color[4] = {0.0, 1.0, 0.0, 1.0};

    if (self.previousPoint != nil) {
        CGContextSetRGBStrokeColor(offScreenBuffer, color[0], color[1], color[2], color[3]);

        CGContextBeginPath(offScreenBuffer);
        CGContextSetLineWidth(offScreenBuffer, 10.0);
        CGContextSetLineCap(offScreenBuffer, kCGLineCapRound);

        CGContextMoveToPoint(offScreenBuffer, previousPoint.location.x, previousPoint.location.y);
        CGContextAddLineToPoint(offScreenBuffer, point.location.x, point.location.y);

        CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeColor);

        CGContextDrawPath(offScreenBuffer, kCGPathStroke);
    }    
}

- (void)drawPoint:(UITouch *)touch {

    PointLocation *currentLoc = [[PointLocation alloc] init];

    currentLoc.location = [touch locationInView:self];

    self.previousPoint = self.point;

    self.point = currentLoc;
    [self drawToBuffer];

    [self setNeedsDisplay];

    [currentLoc release];
}

person sree_iphonedev    schedule 19.06.2012    source источник


Ответы (2)


Это очень просто. Вам нужно сделать весь свой рисунок в drawRect:, а вы рисуете только изображение в drawRect:, поэтому вы видите только изображение.

person Erik B    schedule 19.06.2012

-(void)drawPic:(UIImage *)thisPic {
//code for UIViewContentModeScaleAspectFit if needed
self.backgroundColor = [UIColor colorWithPatternImage:thisPic];
[self setNeedsDisplay];
}

Не используйте это в методе drawRect:

[myPic drawInRect:CGRectMake(xPos, yPos, newWidth, newHeight)];

Изменить

- (void)drawRect:(CGRect)rect {

if (!myDrawing) {

//      CGFloat scale = 0.5;
//      CATransform3D transform = CATransform3DMakeScale(scale, scale, scale);
//      [self layer].transform = transform;
    myDrawing = [[NSMutableArray alloc] initWithCapacity:0];
    self.lineOnOffArray = [[NSMutableArray alloc] initWithCapacity:0];

    //arrPenThickness = [[NSMutableArray alloc] initWithCapacity:0];
}

CGContextRef ctx = UIGraphicsGetCurrentContext();

if ([myDrawing count] > 0) {

    for (int i = 0 ; i < [myDrawing count] ; i++) {
        NSArray *thisArray = [myDrawing objectAtIndex:i];

        NSString  *onOffFlag = [self.lineOnOffArray objectAtIndex:i];

        if (([thisArray count] > 2) && (onOffFlag == @"1")){
            float penT = [[arrPenThickness objectAtIndex:i] floatValue];
            NSString* penC = [arrPenColors objectAtIndex:i];

            NSArray *arr = [penC componentsSeparatedByString:@","];

            float   r = [[arr objectAtIndex:0]floatValue];
            float   g = [[arr objectAtIndex:1]floatValue];
            float   b = [[arr objectAtIndex:2]floatValue];
            float   a = [[arr objectAtIndex:3]floatValue];
            CGContextSetRGBStrokeColor(ctx, 
                                       r/255.0,
                                       g/255.0,
                                       b/255.0,
                                       a);

            CGContextSetLineCap(ctx, kCGLineCapRound);
            CGContextSetLineWidth(ctx, penT);
            float thisX = [[thisArray objectAtIndex:0] floatValue];
            float thisY = [[thisArray objectAtIndex:1] floatValue];

            CGContextBeginPath(ctx);


            for (int j = 2; j < [thisArray count] ; j+=2) {

                CGContextMoveToPoint(ctx, thisX, thisY);
                thisX = [[thisArray objectAtIndex:j] floatValue];
                thisY = [[thisArray objectAtIndex:j+1] floatValue];
                CGContextAddLineToPoint(ctx, thisX,thisY);
            }

            CGContextStrokePath(ctx);

        }
    }
}

}
person Warif Akhand Rishi    schedule 19.06.2012
comment
Дорогой Вариф, я сделал, как ты сказал. Но все же я получаю ту же ошибку «Ошибка»: CGContextSetBlendMode: неверный контекст 0x0, как и раньше. Если я не добавлю изображение в метод drawRect, а вместо этого использую следующий код CGImageRef cgImage = CGBitmapContextCreateImage(offScreenBuffer); UIImage *uiImage = [[UIImage alloc] initWithCGImage:cgImage]; CGImageRelease(cgImage); [uiImage drawInRect:self.bounds]; [выпуск uiImage]; Я смогу рисовать поверх UIView. Но я пытаюсь нарисовать изображение и сохранить его в библиотеке фотографий устройства. Помогите мне, пожалуйста. - person sree_iphonedev; 20.06.2012
comment
Ответ отредактирован. Изменяемые массивы не будут соответствовать вашему коду. посмотрите, как CGContextAddLineToPoint в цикле. Мне не нужен был CGContextSetBlendMode. - person Warif Akhand Rishi; 20.06.2012