I have already implemented paint / draw using:
- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event
-(void) touchesMoved: (NSSet *) touches withEvent: (UIEvent *) event
- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event
Now issue is that for any line drawn, I want to get that particular line / paint image. I don't want image of entire screen, only area / bounds of line / paint drawn.
Reason is that I want to perform pan gesture / delete functionality on that line / paint drawn.
User can draw multiple lines, so want UIImage
for all this lines separately.
Any logic or code snippet will be really helpful
Thanks in advance
Depending on your application, particularly how many times you plan on doing this in a row, you may be able to create a different image/layer for each paint line. Your final image would essentially be all the individual lines drawn on top of each other.
It may be more efficient to create a custom view to capture touch events. You could store the list of touch coordinates for each paint line and render them all at once in a custom drawRect. This way you are storing lists of coordinates for each paint line, and can still access each one, instead of a list of images. You could calculate the area/bounds from the coordinates used to render the line.
Additional context and code may be helpful, I'm not sure I completely understand what you're trying to accomplish!
I take a look at the MVPaint project. It seems you have an object:
MVPaintDrawing
_drawing;
which contains an array of MVPaintTransaction
. You can iterate on those MVPaintTransaction
to draw an UIImage
.
So first you can add a method to get an image from a 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;
}
Then add a method to get an array of image from the array of MVPaintTransaction
in the MVPaintDrawing
class:
- (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;
}
In this way you will have an array of UIImage
corresponding to each line you have drawn. If you want those images to have the "minimum" possible size (i mean without extra alpha part), you can apply this method (I added it in the MVPaintTransaction
class):
- (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;
}
Then simply replace in the first method:
return result;
by
return [self trimmedImage:result];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With