Для меня основное отличие, чтобы выбрать BeanFactory
над ApplicationContext
, похоже, что ApplicationContext
будет предварительно создавать все бобы. Из Spring docs:
Spring устанавливает свойства и разрешает зависимости как можно позже, когда компонент фактически создан. Это означает, что контейнер Spring, который правильно загрузился, может позже генерировать исключение, когда вы запрашиваете объект, если есть проблема с созданием этого объекта или одной из его зависимостей. Например, бит генерирует исключение в результате отсутствия или недопустимого свойства. Эта потенциально задержка видимости некоторых проблем с конфигурацией заключается в том, что реализации ApplicationContext по умолчанию представляют собой предварительные экземпляры одноэлементных бэнов. За счет некоторого времени и памяти для создания этих компонентов до того, как они действительно понадобятся, вы обнаружите проблемы с конфигурацией при создании ApplicationContext, а не позже. Вы по-прежнему можете переопределить это поведение по умолчанию, так что однопользовательские beans будут lazy-initialize, а не быть предварительно созданными.
blockquote>Учитывая это, я изначально выбрал
BeanFactory
для использования в тестах интеграции / производительности так как я не хотел загружать все приложение для тестирования изолированных бобах. Однако - и кто-то меня исправит, если я ошибаюсь -BeanFactory
не поддерживает конфигурацию XMLclasspath
. Таким образом,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); } } }
Надеюсь, это поможет вам,
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()
Всего наилучшего:)
Таким образом, оверлейная картинка будет намного чище
class func mergeImages(imageView: UIImageView) -> UIImage {
UIGraphicsBeginImageContextWithOptions(imageView.frame.size, false, 0.0)
imageView.superview!.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
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
}
}
Слегка измененная версия ответа от Будидино. Эта реализация также правильно обрабатывает отрицательные 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
}
}
Ответ с поправкой растягивает фоновое изображение, изменяя его соотношение. Приведенное ниже решение исправляет это путем рендеринга изображения из 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
}
Возвращенные данные изображения удваивают размер изображения, поэтому установите размер просмотров на половину желаемый размер.
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)
}
Объективная версия 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;
}
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
}
}