2016-06-30 15 views
10

tôi đã thực hiện sơn/vẽ sử dụng:Bắt UIImage chỉ giới hạn khu vực cụ thể rút ra - PaintView

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

Bây giờ vấn đề là đối với bất kỳ dòng rút ra, tôi muốn nhận được rằng hình ảnh dòng/sơn đặc biệt. Tôi không muốn hình ảnh của toàn bộ màn hình, chỉ khu vực/giới hạn của dòng/sơn vẽ.

Lý do là tôi muốn thực hiện chức năng cử chỉ/xóa trên dòng/sơn vẽ đó.

Người dùng có thể vẽ nhiều dòng, vì vậy, muốn UIImage cho tất cả các dòng này riêng biệt.

Bất kỳ logic hoặc đoạn mã đó sẽ thực sự hữu ích

Cảm ơn trước

Trả lời

1

Tùy thuộc vào ứng dụng của bạn, đặc biệt là bao nhiêu lần bạn có kế hoạch thực hiện điều này trong một hàng, bạn có thể tạo ra một khác nhau hình ảnh/lớp cho mỗi dòng sơn. Hình ảnh cuối cùng của bạn về bản chất sẽ là tất cả các dòng riêng lẻ được vẽ lên nhau.

Có thể hiệu quả hơn khi tạo chế độ xem tùy chỉnh để nắm bắt các sự kiện chạm. Bạn có thể lưu trữ danh sách các tọa độ cảm ứng cho mỗi dòng sơn và hiển thị chúng cùng một lúc trong một drawRect tùy chỉnh. Bằng cách này, bạn đang lưu trữ danh sách tọa độ cho từng đường vẽ và vẫn có thể truy cập từng danh sách, thay vì danh sách hình ảnh. Bạn có thể tính toán diện tích/giới hạn từ các tọa độ được sử dụng để hiển thị dòng.

Ngữ cảnh và mã bổ sung có thể hữu ích, tôi không chắc tôi hoàn toàn hiểu những gì bạn đang cố gắng hoàn thành!

+0

Bất kỳ đoạn mã sẽ rất hữu ích –

+0

Nó sẽ rất hữu ích nếu bạn đăng sơn của bạn/vẽ phương pháp để bản thân mình hoặc người khác có thể thực hiện điều đó dễ dàng hơn. – bradkratky

+0

Tôi đang sử dụng thư viện này https://github.com/megavolt605/MVPaint –

1

Tôi xem dự án MVPaint. Dường như bạn có một đối tượng:

MVPaintDrawing _drawing;

có chứa một mảng MVPaintTransaction. Bạn có thể lặp lại trên những số MVPaintTransaction để vẽ UIImage.

Vì vậy, đầu tiên bạn có thể thêm một phương pháp để có được một hình ảnh từ một MVPaintTransaction:

- (UIImage *) imageToDrawWithSize:(CGSize) size xScale:(CGFloat)xScale yScale:(CGFloat)yScale { 

    UIGraphicsBeginImageContext(size); 
    CGContextScaleCTM(UIGraphicsGetCurrentContext(), xScale, yScale); 

    // call the existing draw method  
    [self draw]; 

    UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return result; 
} 

Sau đó, thêm một phương pháp để có được một loạt các hình ảnh từ các mảng MVPaintTransaction trong lớp MVPaintDrawing:

- (NSArray *) getImagesFromDrawingOnSurface: (UIImageView *) surface xScale: (CGFloat) xScale yScale: (CGFloat) yScale{ 

    NSMutableArray *imageArray = [NSMutableArray new]; 
    for (MVPaintTransaction * transaction in _drawing) { 
     UIImage *image = [transaction imageToDrawWithSize:surface.frame.size xScale:xScale yScale:yScale]; 
     [imageArray addObject:image]; 
    } 

    return imageArray; 
} 

Bằng cách này, bạn sẽ có một mảng UIImage tương ứng với mỗi dòng bạn đã vẽ. Nếu bạn muốn những hình ảnh có kích thước "tối thiểu" có thể (tôi có nghĩa là không có phần alpha thêm), bạn có thể áp dụng this method (tôi đã thêm nó vào lớp MVPaintTransaction):

- (UIImage *)trimmedImage:(UIImage *)img { 

    CGImageRef inImage = img.CGImage; 
    CFDataRef m_DataRef; 
    m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage)); 

    UInt8 * m_PixelBuf = (UInt8 *) CFDataGetBytePtr(m_DataRef); 

    size_t width = CGImageGetWidth(inImage); 
    size_t height = CGImageGetHeight(inImage); 

    CGPoint top,left,right,bottom; 

    BOOL breakOut = NO; 
    for (int x = 0;breakOut==NO && x < width; x++) { 
     for (int y = 0; y < height; y++) { 
      int loc = x + (y * width); 
      loc *= 4; 
      if (m_PixelBuf[loc + 3] != 0) { 
       left = CGPointMake(x, y); 
       breakOut = YES; 
       break; 
      } 
     } 
    } 

    breakOut = NO; 
    for (int y = 0;breakOut==NO && y < height; y++) { 

     for (int x = 0; x < width; x++) { 

      int loc = x + (y * width); 
      loc *= 4; 
      if (m_PixelBuf[loc + 3] != 0) { 
       top = CGPointMake(x, y); 
       breakOut = YES; 
       break; 
      } 

     } 
    } 

    breakOut = NO; 
    for (int y = height-1;breakOut==NO && y >= 0; y--) { 

     for (int x = width-1; x >= 0; x--) { 

      int loc = x + (y * width); 
      loc *= 4; 
      if (m_PixelBuf[loc + 3] != 0) { 
       bottom = CGPointMake(x, y); 
       breakOut = YES; 
       break; 
      } 

     } 
    } 

    breakOut = NO; 
    for (int x = width-1;breakOut==NO && x >= 0; x--) { 

     for (int y = height-1; y >= 0; y--) { 

      int loc = x + (y * width); 
      loc *= 4; 
      if (m_PixelBuf[loc + 3] != 0) { 
       right = CGPointMake(x, y); 
       breakOut = YES; 
       break; 
      } 

     } 
    } 


    CGFloat scale = img.scale; 

    CGRect cropRect = CGRectMake(left.x/scale, top.y/scale, (right.x - left.x)/scale, (bottom.y - top.y)/scale); 
    UIGraphicsBeginImageContextWithOptions(cropRect.size, 
              NO, 
              scale); 
    [img drawAtPoint:CGPointMake(-cropRect.origin.x, -cropRect.origin.y) 
      blendMode:kCGBlendModeCopy 
       alpha:1.]; 
    UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    CFRelease(m_DataRef); 
    return croppedImage; 
} 

Sau đó chỉ cần thay thế trong phương pháp đầu tiên :

return result; 

bởi

return [self trimmedImage:result]; 
+0

Không có điều này không hoạt động, tôi đã thử mã của bạn –

+0

Tôi cũng đã thử nó trước khi đăng và nếu tôi gọi getImagesFromDrawingOnSurface, tôi nhận được một mảng UIImage (mỗi hình ảnh đại diện cho một đường vẽ mà là những gì bạn yêu cầu). Mã của tôi không thay đổi cách hiển thị các dòng (để thực hiện điều này, bạn có thể cần tạo mảng UIImageView chẳng hạn). –

Các vấn đề liên quan