Как объединить два UIImages?

Для меня основное отличие, чтобы выбрать BeanFactory над ApplicationContext, похоже, что ApplicationContext будет предварительно создавать все бобы. Из Spring docs:

Spring устанавливает свойства и разрешает зависимости как можно позже, когда компонент фактически создан. Это означает, что контейнер Spring, который правильно загрузился, может позже генерировать исключение, когда вы запрашиваете объект, если есть проблема с созданием этого объекта или одной из его зависимостей. Например, бит генерирует исключение в результате отсутствия или недопустимого свойства. Эта потенциально задержка видимости некоторых проблем с конфигурацией заключается в том, что реализации ApplicationContext по умолчанию представляют собой предварительные экземпляры одноэлементных бэнов. За счет некоторого времени и памяти для создания этих компонентов до того, как они действительно понадобятся, вы обнаружите проблемы с конфигурацией при создании ApplicationContext, а не позже. Вы по-прежнему можете переопределить это поведение по умолчанию, так что однопользовательские beans будут lazy-initialize, а не быть предварительно созданными.

Учитывая это, я изначально выбрал BeanFactory для использования в тестах интеграции / производительности так как я не хотел загружать все приложение для тестирования изолированных бобах. Однако - и кто-то меня исправит, если я ошибаюсь - BeanFactory не поддерживает конфигурацию XML classpath. Таким образом, BeanFactory и ApplicationContext каждый из них предоставляет важную функцию, которую я хотел, но также и то и другое.

Рядом, как я могу судить, примечание в документации об переопределении поведения экземпляра по умолчанию происходит в конфигурации, и это per-bean, поэтому я не могу просто установить атрибут «lazy-init» в файле XML, или я застрял, поддерживая его версию для тестирования, а другой для развертывания.

Что я в конечном итоге делалось расширение ClassPathXmlApplicationContext до лениво загружаемых бобов для использования в тестах следующим образом:

public class LazyLoadingXmlApplicationContext extends ClassPathXmlApplicationContext {

    public LazyLoadingXmlApplicationContext(String[] configLocations) {
        super(configLocations);
    }

    /**
     * Upon loading bean definitions, force beans to be lazy-initialized.
     * @see org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
     */

    @Override
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
        super.loadBeanDefinitions(reader);
        for (String name: reader.getBeanFactory().getBeanDefinitionNames()) {
            AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) reader.getBeanFactory().getBeanDefinition(name);
            beanDefinition.setLazyInit(true);
        }
    }

}
29
задан Luca Alberto 14 August 2015 в 16:47
поделиться

8 ответов

Надеюсь, это поможет вам,

var bottomImage = UIImage(named: "bottom.png")
var topImage = UIImage(named: "top.png")

var size = CGSize(width: 300, height: 300)
UIGraphicsBeginImageContext(size)

let areaSize = CGRect(x: 0, y: 0, width: size.width, height: size.height)
bottomImage!.draw(in: areaSize)

topImage!.draw(in: areaSize, blendMode: .normal, alpha: 0.8)

var newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()

Всего наилучшего:)

73
ответ дан Pineapple3D 14 August 2015 в 16:47
поделиться

Таким образом, оверлейная картинка будет намного чище

class func mergeImages(imageView: UIImageView) -> UIImage {
 UIGraphicsBeginImageContextWithOptions(imageView.frame.size, false, 0.0) 
 imageView.superview!.layer.renderInContext(UIGraphicsGetCurrentContext()!)
 let image = UIGraphicsGetImageFromCurrentImageContext()
 UIGraphicsEndImageContext()

 return image 
}

enter image description here

14
ответ дан Svitlana 14 August 2015 в 16:47
поделиться

Swift 4 UIImage расширение, которое позволяет легко объединять / накладывать изображения.

extension UIImage { 

  func overlayWith(image: UIImage, posX: CGFloat, posY: CGFloat) -> UIImage {
    let newWidth = size.width < posX + image.size.width ? posX + image.size.width : size.width
    let newHeight = size.height < posY + image.size.height ? posY + image.size.height : size.height
    let newSize = CGSize(width: newWidth, height: newHeight)

    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
    draw(in: CGRect(origin: CGPoint.zero, size: size))
    image.draw(in: CGRect(origin: CGPoint(x: posX, y: posY), size: image.size))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()

    return newImage
  }

}
9
ответ дан budidino 14 August 2015 в 16:47
поделиться

Слегка измененная версия ответа от Будидино. Эта реализация также правильно обрабатывает отрицательные posX и posY.

extension UIImage {
    func overlayWith(image: UIImage, posX: CGFloat, posY: CGFloat) -> UIImage {
        let newWidth = posX < 0 ? abs(posX) + max(self.size.width, image.size.width) :
            size.width < posX + image.size.width ? posX + image.size.width : size.width
        let newHeight = posY < 0 ? abs(posY) + max(size.height, image.size.height) :
            size.height < posY + image.size.height ? posY + image.size.height : size.height
        let newSize = CGSize(width: newWidth, height: newHeight)

        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
        let originalPoint = CGPoint(x: posX < 0 ? abs(posX) : 0, y: posY < 0 ? abs(posY) : 0)
        self.draw(in: CGRect(origin: originalPoint, size: self.size))
        let overLayPoint = CGPoint(x: posX < 0 ? 0 : posX, y: posY < 0 ? 0 : posY)
        image.draw(in: CGRect(origin: overLayPoint, size: image.size))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        return newImage
    }
}
1
ответ дан GOR 14 August 2015 в 16:47
поделиться

Ответ с поправкой растягивает фоновое изображение, изменяя его соотношение. Приведенное ниже решение исправляет это путем рендеринга изображения из UIView, которое содержит два изображения в качестве подпредставлений.

ОТВЕТЬТЕ, ЧТО ВЫ ИЩЕТЕ (Swift 4):

func blendImages(_ img: UIImage,_ imgTwo: UIImage) -> Data? {
    let bottomImage = img
    let topImage = imgTwo

    let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width: 306, height: 306))
    let imgView2 = UIImageView(frame: CGRect(x: 0, y: 0, width: 306, height: 306))

    // - Set Content mode to what you desire
    imgView.contentMode = .scaleAspectFill
    imgView2.contentMode = .scaleAspectFit

    // - Set Images
    imgView.image = bottomImage
    imgView2.image = topImage

    // - Create UIView
    let contentView = UIView(frame: CGRect(x: 0, y: 0, width: 306, height: 306))
    contentView.addSubview(imgView)
    contentView.addSubview(imgView2)

    // - Set Size
    let size = CGSize(width: 306, height: 306)

    // - Where the magic happens
    UIGraphicsBeginImageContextWithOptions(size, true, 0)

    contentView.drawHierarchy(in: contentView.bounds, afterScreenUpdates: true)

    guard let i = UIGraphicsGetImageFromCurrentImageContext(),
        let data = UIImageJPEGRepresentation(i, 1.0)
        else {return nil}

    UIGraphicsEndImageContext()

    return data
}

Возвращенные данные изображения удваивают размер изображения, поэтому установите размер просмотров на половину желаемый размер.

  • ПРИМЕР: я хотел, чтобы ширина и высота изображения были 612 , поэтому я установил ширину и высоту рамки просмотра на 306 ) // Наслаждайтесь:)
0
ответ дан kuzdu 14 August 2015 в 16:47
поделиться
    let imagePickerController = UIImagePickerController()
    imagePickerController.delegate = self
    let actionSheet = UIAlertController(title: "Photo Source", 
    message:  "Choose a source", preferredStyle: .actionSheet)
    actionSheet.addAction(UIAlertAction(title: "Camera", 
       style:.default, handler: {(action: UIAlertAction)in
        if UIImagePickerController.isSourceTypeAvailable(.camera){
            imagePickerController.sourceType = .camera
            self.present(imagePickerController, 
            animated: true,completion: nil)
        }
        else{
            print("camera is not available")
        }  
    }))
    actionSheet.addAction(UIAlertAction(title: "Photo Library", 
                      style:.default, handler: {(action: UIAlertAction)in
        imagePickerController.sourceType = .photoLibrary
        self.present(imagePickerController, animated: true,
                                        completion: nil)

    }))
    actionSheet.addAction(UIAlertAction(title: "Cancle", 
     style: .cancel, handler: nil))
    self.present(actionSheet, animated: true, completion: nil)

  func imagePickerController(_ picker:UIImagePickerController,       
             didFinishPickingMediaWithInfo info: [String : Any]) 
   {
    let image = info[UIImagePickerControllerOriginalImage] as! UIImage
    myImage.image = image
    picker.dismiss(animated: true, completion: nil)
   }
 func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    picker.dismiss(animated: true, completion: nil)
     }
1
ответ дан Dharasanada paras 14 August 2015 в 16:47
поделиться

Объективная версия C этого решения с перецентрированной логикой верхнего изображения:

-(UIImage *)getImageInclosedWithinAnotherImage
{
    float innerImageSize = 20;
    UIImage *finalImage;

    UIImage *outerImage = [UIImage imageNamed:@"OuterImage.png"];
    UIImage *innerImage = [UIImage imageNamed:@"InnerImage.png"];

    CGSize outerImageSize = CGSizeMake(40, 40); // Provide custom size or size of your actual image
    UIGraphicsBeginImageContext(outerImageSize);

    //calculate areaSize for re-centered inner image
    CGRect areSize = CGRectMake(((outerImageSize.width/2) - (innerImageSize/2)), ((outerImageSize.width/2) - (innerImageSize/2)), innerImageSize, innerImageSize);
    [outerImage drawInRect:CGRectMake(0, 0, outerImageSize.width, outerImageSize.height)];
    [innerImage drawInRect:areSize blendMode:kCGBlendModeNormal alpha:1.0];

    finalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return finalImage;
}
0
ответ дан Miknash 14 August 2015 в 16:47
поделиться

Swift 5: Расширение для UIImage

extension UIImage {
  func mergeWith(topImage: UIImage) -> UIImage {
    let bottomImage = self

    UIGraphicsBeginImageContext(size)

    let areaSize = CGRect(x: 0, y: 0, width: bottomImage.size.width, height: bottomImage.size.height)
    bottomImage.draw(in: areaSize)

    topImage.draw(in: areaSize, blendMode: .normal, alpha: 1.0)

    let mergedImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return mergedImage
  }
}
1
ответ дан 27 November 2019 в 21:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: