كيفية رسم شفاف السكتة الدماغية (أو على أي حال من الواضح جزء من صورة) على اي فون
-
08-07-2019 - |
سؤال
يجب تطبيق صغير الذي يسمح للمستخدم رسم على الشاشة مع الاصبع.لدي UIImageView
حيث توجه المستخدم ، عن طريق إنشاء CGContextRef
ومختلف CG draw
المهام.أنا في المقام الأول رسم خطوط/خطوط مع وظيفة CGContextAddLineToPoint
الآن مشكلتي هي هذه:يمكن للمستخدم رسم خطوط من الألوان المختلفة.أريد أن يعطيه القدرة على استخدام "rubber"
أداة حذف جزء من صورة رسمها حتى الآن مع الاصبع.أنا في البداية لم هذا باستخدام اللون الأبيض عن السكتة الدماغية (مجموعة مع CGContextSetRGBStrokeColor
وظيفة) ولكنه لم ينجح لأن اكتشفت لاحقا أن UIImage
على UIImageView
كان في الواقع خلفية شفافة ، وليس الأبيض...لذلك أنا في نهاية المطاف مع صورة شفافة مع خطوط بيضاء على ذلك!
هناك على أية حال تعيين "transparent"
السكتة الدماغية اللون أو هل هناك أي طريقة أخرى لمسح محتوى CGContextRef
تحت إصبع المستخدم ، وعندما يتحرك ؟ شكرا
المحلول
وهذا سوف تفعل خدعة:
CGContextSetBlendMode(context, kCGBlendModeClear)
نصائح أخرى
وانتهى بي الأمر باستخدام خوارزمية بريزنهام لرسم مستقيم (harkening العودة إلى أيام من ماض عندما أتيحت لي لكتابة حركاتي الرسومات الخاصة) ...
- (void) contextEraseLine:(CGContextRef) ctx from:(CGPoint)startPoint to:(CGPoint) endPoint withThickness:(int)thickness {
int x, cx, deltax, xstep,
y, cy, deltay, ystep,
error, st, dupe;
int x0, y0, x1, y1;
x0 = startPoint.x;
y0 = startPoint.y;
x1 = endPoint.x;
y1 = endPoint.y;
// find largest delta for pixel steps
st = (abs(y1 - y0) > abs(x1 - x0));
// if deltay > deltax then swap x,y
if (st) {
(x0 ^= y0); (y0 ^= x0); (x0 ^= y0); // swap(x0, y0);
(x1 ^= y1); (y1 ^= x1); (x1 ^= y1); // swap(x1, y1);
}
deltax = abs(x1 - x0);
deltay = abs(y1 - y0);
error = (deltax / 2);
y = y0;
if (x0 > x1) { xstep = -1; }
else { xstep = 1; }
if (y0 > y1) { ystep = -1; }
else { ystep = 1; }
for ((x = x0); (x != (x1 + xstep)); (x += xstep))
{
(cx = x); (cy = y); // copy of x, copy of y
// if x,y swapped above, swap them back now
if (st) { (cx ^= cy); (cy ^= cx); (cx ^= cy); }
(dupe = 0); // initialize no dupe
if(!dupe) { // if not a dupe, write it out
//NSLog(@"(%2d, %2d)", cx, cy);
CGContextClearRect(ctx, CGRectMake(cx, cy, thickness, thickness));
}
(error -= deltay); // converge toward end of line
if (error < 0) { // not done yet
(y += ystep);
(error += deltax);
}
}
}
وتفو! هذا هو طريق طويل لنقطعه لإنشاء (إلى حد ما) عالي الكعب خط ممحاة.
لاستخدامها، لا شيء مثل:
- (void)eraseStart {
// erase lines
UIGraphicsBeginImageContext(drawingBoard.size);
ctx = UIGraphicsGetCurrentContext();
CGContextDrawImage(ctx,CGRectMake(0,0,drawingBoard.size.width, drawingBoard.size.height),[drawingBoard CGImage]);
}
- (void)eraseEnd {
drawingBoard = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[drawingView removeFromSuperview];
[drawingView release];
drawingView = [[UIImageView alloc] initWithImage:drawingBoard];
drawingView.frame = CGRectMake(intEtchX, intEtchY, intEtchWidth, intEtchHeight);
[self.view addSubview:drawingView];
}
وهذا يفترض أنك قد قمت بالفعل بإنشاء drawingView (UIImageView) وdrawingBoard (UIImage).
وبعد ذلك، لمحو خط، فلا تفعل شيئا مثل:
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self eraseStart];
[self contextEraseLine:ctx from:CGPointMake (x1, y1) to:CGPointMake (x2, y2) withThickness:10];
[self eraseEnd];
و(استبدال X1، Y1، X2، Y2 ومع القيم المناسبة) ...
لقد حاولت استخدام:
CGContextSetStrokeColorWithColor (myContext, [[UIColor clearColor] CGColor]);
ولكن هذا لا يعمل, لأنه يبدو أن "الرسم" على رأس السياق مع غير مرئية اللون (غير مرئية اللون + أي لون هو الرسم على = اللون هو الرسم على).
الحل الوحيد لقد وجدت (وهي ليست الأمثل) هو:
CGContextClearRect (myContext, CGRectMake(x, y, width, height));
للأسف, هذا يعني أن عليك أن تتبع سلسلة من rects وتوليد الخط نفسك...
إذا كنت تريد أن تمحو صورة مع لمسة وهذا هو قانون بلدي .... الجزء نيراسي لا ينصح أنها تعمل ولكن بطيئة قليلا.
func addNewPathToImage(){
print("Start erasing or not erasing")
UIGraphicsBeginImageContextWithOptions(TopImageUIImageView.bounds.size, false, UIScreen.main.scale) // or 0 for the scale
//My image is aspect fit so I need to get rect
let aspect = TopImageUIImageView.image!.size.width / TopImageUIImageView.image!.size.height
let viewRatio = TopImageUIImageView.bounds.size.width / TopImageUIImageView.bounds.size.height
if aspect < viewRatio {
let scale = TopImageUIImageView.bounds.size.height / TopImageUIImageView.image!.size.height
let width = scale * TopImageUIImageView.image!.size.width
let topLeftX = (TopImageUIImageView.bounds.size.width - width) * 0.5
rect = CGRect(x: topLeftX, y: 0, width: width, height: TopImageUIImageView.bounds.size.height)
}
else {
let scale = TopImageUIImageView.bounds.size.width / TopImageUIImageView.image!.size.width
let height = scale * TopImageUIImageView.image!.size.height
let topLeftY = (TopImageUIImageView.bounds.size.height - height) * 0.5
rect = CGRect(x: 0.0, y: topLeftY, width: TopImageUIImageView.bounds.size.width, height: height)
}
////
context = UIGraphicsGetCurrentContext()
TopImageUIImageView.image?.draw(in: rect)
context?.setLineCap(.round)
context?.setLineWidth(brushSize)
if isErasing == true {
context?.setShadow(offset: CGSize(width: 0, height: 0), blur: blurNumber)
context?.setStrokeColor(UIColor.white.cgColor)
context?.setBlendMode(.clear)
}else{
print("test the unerase image .... ?")
context?.setStrokeColor(UIColor.init(patternImage: topImage.af_imageAspectScaled(toFit: CGSize(width: TopImageUIImageView.bounds.size.width, height: TopImageUIImageView.bounds.size.height))).cgColor)
}
// I am using these because I am using touch to define what to erase
context?.move(to: CGPoint(x: lastTouch.x, y: lastTouch.y))
context?.addLine(to: CGPoint(x: currentTouch.x, y: currentTouch.y))
context?.strokePath()
context?.closePath() // when add this line or the "context?.beginPath" get ERROR CGContextClosePath: no current point.
print("close the path")
//get your image
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
TopImageUIImageView.image = image
}
//erase part
if(mouseSwiped)
{
//**************Working Code*************//
UIGraphicsBeginImageContext(frontImage.frame.size);
[frontImage.image drawInRect:CGRectMake(0, 0, frontImage.frame.size.width, frontImage.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(),kCGImageAlphaNone); //kCGImageAlphaPremultipliedLast);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 10);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1, 0, 0, 10);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextClearRect (UIGraphicsGetCurrentContext(), CGRectMake(lastPoint.x, lastPoint.y, 10, 10));
CGContextStrokePath(UIGraphicsGetCurrentContext());
frontImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
mouseMoved++;
if (mouseMoved == 10)
{
mouseMoved = 0;
}
}
UIColor *clearColor = [UIColor clearColor];