#ios #uiimage #core-graphics #calayer #cashapelayer
#iOS #uiimage #ядро-графика #calayer #cashapelayer
Вопрос:
Я хочу объединить два изображения с добавлением пограничного слоя Zigzag между ними.
Вот пример изображения, которое я хочу интегрировать в свое приложение.
Как я могу добиться такого типа иллюзии между двумя изображениями? я также пробовал маскировать изображение, но это не дает мне результата, который я должным образом хочу.
Пожалуйста, помогите мне с этим. Будем признательны за любые предложения. Спасибо
Ответ №1:
Надеюсь, это поможет кому-то, кто все еще хочет достичь чего-то подобного…Вы можете выполнить эту задачу всего за 2 шага, описанных ниже, или, если вы спешите, сразу переходите к полностью прокомментированному коду, который делает именно то, чего вы хотите достичь.
Шаг 1: Сделайте 2 изображения, которые вы хотите объединить. Создайте обтравочный контур Безье с зигзагообразными краями для первого изображения. Верните составное изображение из графического контекста.
Шаг 2: Запустите новый графический контекст, нарисуйте второе изображение (справа) в графическом контексте таким, какое оно есть. Затем нарисуйте составное изображение, полученное на шаге 1 выше. Затем создайте зигзагообразный контур с помощью UIBezierPath, задайте ширину линии и обведите контур белым цветом. Получите окончательное изображение в вышеуказанном стиле из графического контекста. Вот и все, что нужно!
Пример использования :
UIImage *firstImage = [UIImage imageNamed:@"firstImage.png"];
UIImage *secondImage = [UIImage imageNamed:@"secondImage.png"];
self.imageView.image = [self zigZagImageFrom:firstImage secondImage:secondImage];
Код:
/*
Create image with "zigzag" separator line from 2 source images
Steps to acheive the desired output:
1: Create first image with zigzag edge on the right - change value of "width" variable as necessary to extend/reduce the visible area other than zigzag edge.
2: Draw "second image" in the context (canvas) as it is, but overlayed by first image with zigzag edge generated in the step 1 above. Draw zigzag line in desired color on the image from step2 above using the same curve path.
*/
(UIImage *)zigZagImageFrom:(UIImage *)firstImage secondImage:(UIImage *)secondimage
{
CGFloat width = firstImage.size.width/2; //how much of the first image you would want to keep visible other than the zigzag edges.
CGFloat height = firstImage.size.height;
int totalZigzagCurves = 20; // total no of waypoints in the zigzag path.
CGFloat zigzagCurveWidth = width/30; // width of a single zigzag curve line.
CGFloat zigzagCurveHeight = height/totalZigzagCurves; //height of a single zigzag curve line.
CGFloat scale = [[UIScreen mainScreen] scale];
UIGraphicsBeginImageContextWithOptions(firstImage.size, NO, scale);
// -- STEP 1 --
//We will make a clipping path in zigzag style
UIBezierPath *zigzagPath = [[UIBezierPath alloc] init];
//Begining point of the zigzag path
[zigzagPath moveToPoint:CGPointMake(0, 0)];
//draw zigzag path starting from somewhere middle on the top to bottom. - must be same for zigzag line in step 3.
int a=-1;
for (int i=0; i<totalZigzagCurves 2; i ) {
[zigzagPath addLineToPoint:CGPointMake(width (zigzagCurveWidth*a), zigzagCurveHeight*i [self randomCurvePoint:i])];
a= a*-1;
}
[zigzagPath addLineToPoint:CGPointMake(0, height)];
//remove the remaining (right side) of image using zigzag path.
[zigzagPath addClip];
[firstImage drawAtPoint:CGPointMake(0, 0)];
//Output first image with zigzag edge.
UIImage *firstHalfOfImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//We have the first image with zigzag edge. Now draw it over the second source image followed by zigzag line
UIGraphicsBeginImageContextWithOptions(firstImage.size, YES, scale);
// -- STEP 2 --
//draw first amp; second image so that we can draw the zigzag line on it.
[secondimage drawAtPoint:CGPointMake(0, 0)];
[firstHalfOfImage drawAtPoint:CGPointMake(0, 0)];
// -- STEP 3 --
//Draw zigzag line over image using same curves.
zigzagPath = [[UIBezierPath alloc] init];
//Begining point of the zigzag line
[zigzagPath moveToPoint:CGPointMake(width, -5)];
//draw zigzag line path starting from somewhere middle on the top to bottom.
a=-1;
for (int i=0; i<totalZigzagCurves 2; i ) {
[zigzagPath addLineToPoint:CGPointMake(width (zigzagCurveWidth*a), zigzagCurveHeight*i [self randomCurvePoint:i])];
a= a*-1;
}
//Set color for zigzag line.
[[UIColor whiteColor] setStroke];
//Set width for zigzag line.
[zigzagPath setLineWidth:6.0];
//Finally, draw zigzag line over the image.
[zigzagPath stroke];
//Output final image with zigzag.
UIImage *zigzagImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//Desired output
return zigzagImage;
}
//To make some of the zigzag curves/waypoints with variable height
(int)randomCurvePoint:(int)value{
if (value == 0 || value == 2 ) return -8;
else if (value == 4 || value == 5 || value == 17 || value == 18) return 28;
else if (value == 16 || value == 8 || value == 9 || value == 19) return 2;
else if (value == 12 || value == 13 || value == 14 || value == 15) return -29;
else return 1;
}
Результирующий пример изображения:
Извините за мою неспособность опубликовать пример изображения из приведенного выше примера кода. К сожалению, мне нужно не менее 10 баллов репутации, чтобы иметь возможность публиковать изображения. Поскольку это мой первый пост, мне не разрешено его публиковать.
Спасибо за поддерживающий ответ. Вот результирующее изображение:
СОВЕТ: сделайте это категорией в UIImage
Комментарии:
1. это потрясающе, чувак.. работает как по волшебству :).. Огромное спасибо.. ты гениальный человек.. ценю вашу работу!! @vjswami
Ответ №2:
Я бы создал CGPath
для достижения этой цели. Вы могли бы вычислить его зигзагообразность на ходу, в зависимости от высоты нужного изображения. (игнорируйте левое изображение, правое будет располагаться поверх него).
Затем, что вы делаете, это создаете контур с зигзагообразной линией слева (начинаете с точки, добавляете линию к x 8 / y 24, добавляете линию к x-8 / y 15 и повторяетесь), а затем включаете всю область справа (добавляете 3 прямые линии прямоугольника).
После этого создайте CAShapeLayer
(который принимает CGPathRef!) и передайте путь, который вы только что создали. Установите его в качестве маски слоя. Последний шаг: в вашей drawInRect:
части UImageView отобразите тот же экземпляр path, используя только белую обводку нужной ширины.
Удачи!
Комментарии:
1. спасибо за ваше предложение, я пробовал. но не получается точного эффекта, который я хочу. ценю ваши усилия.