Слияние ранее повернутого жестом UIImageView с другим. WYS не WYG - PullRequest
2 голосов
/ 08 июля 2011

Я схожу с ума, пытаясь объединить два UIImageView.

Ситуация:

  • фоновый UIImageView (userPhotoImageView)
  • наложение UIImageView (productPhotoImageView) которые могут быть растянуты, зажаты и повернутый

Я вызываю свою функцию в UIImages, но я могу взять координаты и новый растянутый размер из содержащего их UIImageView (они синтезированы в моем классе)

    - (UIImage *)mergeImage:(UIImage *)bottomImg withImage:(UIImage *)topImg;

Возможно, самым простым способом было бы визуализировать слой верхнего UIImageView в новом CGContextRef следующим образом:

    [bottomImg drawInRect:CGRectMake(0, 0, bottomImg.size.width, bottomImg.size.height)];
    [productPhotoImageView.layer renderInContext:ctx];

Но таким образом я теряю эффект вращения, ранее примененный жестами.

Второй способ - попытаться применить AffineTransformation к UIImage, чтобы воспроизвести эффекты GestureEffects, а затем нарисовать его в следующем контексте:

    UIImage * scaledTopImg = [topImg imageByScalingProportionallyToSize:productPhotoView.frame.size];
    UIImage * rotatedScaledTopImg = [scaledTopImg imageRotatedByDegrees:ANGLE];    
    [rotatedScaledTopImg drawAtPoint:CGPointMake(productPhotoView.frame.origin.x, productPhotoView.frame.origin.y)];

Проблема этого второго подхода заключается в том, что я не могу точно получить конечное количество градусов поворота (параметр ANGLE, который должен быть указан в приведенном выше коде), так как пользователь начал взаимодействовать, это потому, что RotationGesture сбрасывается до 0 после применения, поэтому следующий обратный вызов является дельтой текущего вращения.

Конечно, самый простой способ - это первый, замораживать два UIImageViews, когда они отображаются в тот самый момент, но на самом деле я все еще не нашел, как это сделать.

Ответы [ 3 ]

3 голосов
/ 08 августа 2011

Замечательно, что было полезно и слишком много обходного пути;)

, так как я вижу, что довольно сложно найти несколько примеров кода для объединения рисунков после того, как манипуляция здесь стала моей, надеюсь, это может быть полезно:1003 *

- (UIImage *)mergeImage:(UIImage *)bottomImg withImage:(UIImage *)topImg {

    UIImage * scaledTopImg = [topImg imageByScalingProportionallyToSize:productPhotoView.frame.size];

    UIGraphicsBeginImageContext(scaledTopImg.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(ctx, scaledTopImg.size.width * 0.5f, scaledTopImg.size.height  * 0.5f);    
    CGFloat angle = atan2(productPhotoView.transform.b, productPhotoView.transform.a);    
    CGContextRotateCTM(ctx, angle);    
    [scaledTopImg drawInRect:CGRectMake(- scaledTopImg.size.width * 0.5f, -(scaledTopImg.size.height  * 0.5f), scaledTopImg.size.width, scaledTopImg.size.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    UIGraphicsBeginImageContext(bottomImg.size);
    [bottomImg drawInRect:CGRectMake(0, 0, bottomImg.size.width, bottomImg.size.height)];    
    [newImage drawInRect:CGRectMake(productPhotoView.frame.origin.x, productPhotoView.frame.origin.y, newImage.size.width, newImage.size.height)];
    UIImage *newImage2 = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();    

    return newImage2;
}

Поскольку я получил фоновое изображение, проще было сначала создать контекст, чтобы просто применить преобразование к наложенному представлению, чем сохранить его и написать поверх нижнего слоя.

Позаботьтесь оперевод CTM перед поворотом наложения, или он будет вращаться вокруг оси, расположенной в {0,0}, в то время как я хочу вращать свое изображение вокруг его центра.

С уважением

3 голосов
/ 26 августа 2011

Хорошо, в принципе, есть еще один обходной путь для всех этих сумасшедших слияний, но это определенно не элегантное решение. Чтобы избежать обработки любого вида AffineTransformation, просто захватите ImageScreen и затем обрежьте его.

CGImageRef screenImage = UIGetScreenImage();
CGRect fullRect = [[UIScreen mainScreen] applicationFrame];
CGImageRef saveCGImage = CGImageCreateWithImageInRect(screenImage, fullRect);
CGRect cropRect = CGRectMake(x,y,width,height);
CGImageRef saveCGImage = CGImageCreateWithImageInRect(screenImage, cropRect);

Сказал, что это не элегантно, но для кого-то это может быть полезно.

0 голосов
/ 26 июля 2011

У меня та же проблема.

У меня проблема только с вращением.

Я использую распознаватели жестов для перемещения, масштабирования и вращения.

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

Теперь это работает

, если вы хотите узнать угол поворота, я получаю его с помощью:

CGFloat angle = atan2(overlay.transform.b, overlay.transform.a);

И вращение с:

CGContextRotateCTM(context, angle);

Если у вас другой подход, пожалуйста, дайте мне знать.

...