- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个类设置,允许用户从他们的库中添加图像,裁剪并保存它。
代码的设置使得如果检索到的图像是纵向的,则在裁剪之前所有图像都会出现一个纵向形状的边框以对齐,如果是横向,则会出现一个横向的边框。
如果选择的图像是规则形状的图像,则一切正常。但是,如果检索到的图像是纵向的而不是常规比例(意味着更接近正方形但实际上不是正方形),则图像在裁剪后会旋转。系统似乎将其视为风景图像。
这是裁剪前后的示例。即使我放大并使图像覆盖整个屏幕,它也会旋转图像:
import Foundation
import UIKit
class SelectImageViewController: UIViewController, UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIScrollViewDelegate{
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var imageConstraintTop: NSLayoutConstraint!
@IBOutlet weak var imageConstraintRight: NSLayoutConstraint!
@IBOutlet weak var imageConstraintLeft: NSLayoutConstraint!
@IBOutlet weak var imageConstraintBottom: NSLayoutConstraint!
var lastZoomScale: CGFloat = -1
var imageName: String = ""
var userPhotoUUID = UUID().uuidString
let userDefault = UserDefaults.standard
var userDatabase: UserDatabase = UserDatabase()
let picker = UIImagePickerController()
@IBOutlet var scrollView: UIScrollView!{
didSet{
scrollView.delegate = self
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 5.0
}
}
@IBOutlet weak var ratioSelector: UISegmentedControl!
@IBOutlet var cropAreaViewL: CropAreaViewL!
var cropAreaL:CGRect{
get{
let factor = imageView.image!.size.width/view.frame.width
let scale = 1/scrollView.zoomScale
let imageFrame = imageView.imageFrame()
let x = (scrollView.contentOffset.x + cropAreaViewL.frame.origin.x - imageFrame.origin.x) * scale * factor
let y = (scrollView.contentOffset.y + cropAreaViewL.frame.origin.y - imageFrame.origin.y) * scale * factor
let width = cropAreaViewL.frame.size.width * scale * factor
let height = cropAreaViewL.frame.size.height * scale * factor
return CGRect(x: x, y: y, width: width, height: height)
}
}
@IBOutlet var cropAreaViewP: CropAreaViewP!
var cropAreaP:CGRect{
get{
let factor = imageView.image!.size.height/view.frame.height
let scale = 1/scrollView.zoomScale
let imageFrame = imageView.imageFrame()
let x = (scrollView.contentOffset.x + cropAreaViewP.frame.origin.x - imageFrame.origin.x) * scale * factor
let y = (scrollView.contentOffset.y + cropAreaViewP.frame.origin.y - imageFrame.origin.y) * scale * factor
let width = cropAreaViewP.frame.size.width * scale * factor
let height = cropAreaViewP.frame.size.height * scale * factor
return CGRect(x: x, y: y, width: width, height: height)
}
}
fileprivate var speciePhotos: Array<SpeciePhotoModel> = [SpeciePhotoModel]()
func randomNumber(range: ClosedRange<Int> = 30000...99998) -> Int {
let min = range.lowerBound
let max = range.upperBound
return Int(arc4random_uniform(UInt32(1 + max - min))) + min
}
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "+", style: .plain, target: self, action: #selector(SelectImageViewController.add(_:)))
let id = randomNumber()
userDefault.set(id, forKey: "photoID")
self.cropAreaViewP.isHidden = true
self.cropAreaViewL.isHidden = true
self.cropAreaViewL.layer.borderColor = (UIColor.red).cgColor
self.cropAreaViewL.layer.borderWidth = 1.0
self.cropAreaViewP.layer.borderColor = (UIColor.red).cgColor
self.cropAreaViewP.layer.borderWidth = 1.0
self.add.layer.cornerRadius = 6.0
self.ratioSelector.layer.cornerRadius = 6.0
self.tabBarController?.tabBar.isHidden = true
self.add.isHidden = true
self.ratioSelector.isHidden = true
updateZoom()
}
func updateConstraints() {
if let image = imageView.image {
let imageWidth = image.size.width
let imageHeight = image.size.height
let viewWidth = scrollView.bounds.size.width
let viewHeight = scrollView.bounds.size.height
// center image if it is smaller than the scroll view
var hPadding = (viewWidth - scrollView.zoomScale * imageWidth) / 2
if hPadding < 0 { hPadding = 0 }
var vPadding = (viewHeight - scrollView.zoomScale * imageHeight) / 2
if vPadding < 0 { vPadding = 0 }
imageConstraintLeft.constant = hPadding
imageConstraintRight.constant = hPadding
imageConstraintTop.constant = vPadding
imageConstraintBottom.constant = vPadding
view.layoutIfNeeded()
}
}
fileprivate func updateZoom() {
if let image = imageView.image {
var minZoom = min(scrollView.bounds.size.width / image.size.width,
scrollView.bounds.size.height / image.size.height)
if minZoom > 1 { minZoom = 1 }
scrollView.minimumZoomScale = 0.3 * minZoom
// Force scrollViewDidZoom fire if zoom did not change
if minZoom == lastZoomScale { minZoom += 0.000001 }
scrollView.zoomScale = minZoom
lastZoomScale = minZoom
}
}
@IBAction func ratioSelector(_ sender: AnyObject) {
switch ratioSelector.selectedSegmentIndex
{
case 0:// Landscape
self.cropAreaViewP.isHidden = true
self.cropAreaViewL.isHidden = false
case 1: // Portrait
self.cropAreaViewL.isHidden = true
self.cropAreaViewP.isHidden = false
default:
break;
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
@IBOutlet weak var add : UIButton!
@IBAction func add(_ sender: UIButton) {
imageView.image = nil
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
picker.allowsEditing = false
self.present(picker, animated: true, completion: nil)
self.ratioSelector.isHidden = false
self.add.isHidden = false
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Crop", style: .plain, target: self, action: #selector(SelectImageViewController.crop(_:)))
}
@IBAction func change(_ sender: UIButton) {
imageView.image = nil
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
picker.allowsEditing = false
self.present(picker, animated: true, completion: nil)
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Crop", style: .plain, target: self, action: #selector(SelectImageViewController.crop(_:)))
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
if chosenImage.size.height > chosenImage.size.width
{
self.cropAreaViewL.isHidden = true
self.cropAreaViewP.isHidden = false
self.ratioSelector.selectedSegmentIndex = 1
imageView.image = chosenImage
}
else
{
self.cropAreaViewP.isHidden = true
self.cropAreaViewL.isHidden = false
self.ratioSelector.selectedSegmentIndex = 0
imageView.image = chosenImage
}
self.dismiss(animated: true, completion: nil)
}
@IBAction func crop(_ sender: UIButton) {
if cropAreaViewP.isHidden == true {
self.cropAreaViewL.layer.borderColor = (UIColor.clear).cgColor
let croppedCGImage = imageView.image?.cgImage?.cropping(to: cropAreaL)
let croppedImage = UIImage(cgImage: croppedCGImage!)
imageView.image = croppedImage
scrollView.zoomScale = 1
} else {
self.cropAreaViewP.layer.borderColor = (UIColor.clear).cgColor
let croppedCGImage = imageView.image?.cgImage?.cropping(to: cropAreaP)
let croppedImage = UIImage(cgImage: croppedCGImage!)
imageView.image = croppedImage
scrollView.zoomScale = 1
}
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(SelectImageViewController.saveButtonAction(_:)))
}
}
extension UIImageView{
func imageFrame()->CGRect{
let imageViewSize = self.frame.size
guard let imageSize = self.image?.size else{return CGRect.zero}
let imageRatio = imageSize.width / imageSize.height
let imageViewRatio = imageViewSize.width / imageViewSize.height
if imageRatio < imageViewRatio { // Portrait
let scaleFactor = imageViewSize.height / imageSize.height
let width = imageSize.width * scaleFactor
let topLeftX = (imageViewSize.width - width) * 0.5
return CGRect(x: topLeftX, y: 0, width: width, height: imageViewSize.height)
}else{ // Landscape
let scaleFactor = imageViewSize.width / imageSize.width
let height = imageSize.height * scaleFactor
let topLeftY = (imageViewSize.height - height) * 0.5
return CGRect(x: 0, y: topLeftY, width: imageViewSize.width, height: height)
}
}
}
class CropAreaViewL: UIView {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return false
}
}
class CropAreaViewP: UIView {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return false
}
}
任何帮助都是巨大的。
最佳答案
您可以使用 max 方法来确保您得到的值不会小于零:
let vPadding = max((viewHeight - scrollView.zoomScale * imageHeight) / 2, 0)
如果你需要让你的图片变成方形,你可以按如下方式做:
extension UIImage {
var isPortrait: Bool { return size.height > size.width }
var isLandscape: Bool { return size.width > size.height }
var breadth: CGFloat { return min(size.width, size.height) }
var breadthSize: CGSize { return CGSize(width: breadth, height: breadth) }
var squared: UIImage? {
guard let cgImage = cgImage?.cropping(to:
CGRect(origin: CGPoint(x: isLandscape ? floor((size.width-size.height)/2) : 0, y: isPortrait ? floor((size.height-size.width)/2) : 0),
size: breadthSize)) else { return nil }
return UIImage(cgImage: cgImage)
}
}
要解决方向问题,您需要重新绘制图像,您可以使用此 answer 中的展平属性.
Playground :
let profilePicture = UIImage(data: try! Data(contentsOf: URL(string:"/image/Xs4RX.jpg")!))!
if let squared = profilePicture.squared {
squared
}
关于swift - UIImage 裁剪后旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42610908/
是否有可能(在 cmd 批处理 ffmpeg 中)拍摄宽度已知(1920px)但高度未知的图像,如果超过,则将高度裁剪为特定的值?基本上是最大高度裁剪。 我玩过缩放和裁剪,但我无法得到我需要的结果。任
我有两个 SpatialPolygonsDataFrame文件:dat1、dat2 extent(dat1) class : Extent xmin : -180 xmax
我在 TensorFlow 上实现了全卷积网络。它使用编码器-解码器结构。训练时,我始终使用相同的图像大小(224x224,使用随机裁剪)并且一切正常。 在干扰阶段,我想一次预测一张图像,因为我想使用
我在 TensorFlow 上实现了全卷积网络。它使用编码器-解码器结构。训练时,我始终使用相同的图像大小(224x224,使用随机裁剪)并且一切正常。 在干扰阶段,我想一次预测一张图像,因为我想使用
我有一个需要裁剪的 View 。我有 4 个 View 显示在主视图上查看的视频 subview 。由于视频比例,我需要裁剪使视频成为正方形而不是矩形的 View 。这是我的代码: - (void)v
我正在构建一个使用 Parse 作为我的后端的网络应用程序。 部分注册过程涉及用户上传和裁剪图片,然后我将其传递到我的数据库(图片是用户个人资料的一部分,类似于您在 Twitter 上所做的)。 我已
我正在制作一个基于立方体的游戏(一切都是立方体),目前正在尝试通过不在视野之外绘制东西来优化它。 以下内容仅适用于 x 和 y 平面,稍后我会担心 z ......所以现在只进行侧面裁剪。 我知道我自
我正在尝试在 iOS 上实现单指图像缩放/裁剪。类似于柯比·特纳的单指旋转。我正在寻找现有的库,或者如果您可以帮助我处理代码本身,那就太好了。 最佳答案 我不太清楚你所说的一指裁剪是什么意思,但我为
从这里: http://www.kylejlarson.com/blog/2011/how-to-create-pie-charts-with-css3/ .pieContainer
我已经设置了一个 SKScene 用作 SKReferenceNode。雪橇是一个 SKSpriteNode,在引用节点场景中定义了一个自定义类,所有的狗都是雪橇 Sprite 的 child 。自定
我有一个库,其中包含一些图像处理算法,包括感兴趣区域(裁剪)算法。使用 GCC 编译时,自动矢量化器会加速很多代码,但会降低 Crop 算法的性能。是否有标记某个循环以被矢量化器忽略的方法,或者是否有
代码位于 http://jsfiddle.net/rSSXu/ Child #parent { margin-left:auto; margin-right:auto;
我搜索了很多以删除不需要的空间,但找不到。我只找到可用于删除黑白背景空间的链接。但我的背景图片可以是任何东西。所以,如果我有这些图片, 我如何提取我需要的图像部分。例如, 最佳答案 这是我对你的问题的
我正在尝试将 CMSampleBufferRef 中的图像裁剪为特定大小。我正在执行 5 个步骤 - 1. 从 SampleBuffer 获取 PixelBuffer 2. 将 PixelBuffer
我读到它是自动的,但在我的案例中似乎没有发生。使用 UIImagePickerController 并将 allowsEditing 设置为 YES 我得到了带有裁剪方形叠加层的编辑 View ,但是
我正在寻找一种高效的方法来裁剪二维数组。考虑这个例子: 我有一个构成 100x100 网格的二维数组。我只想返回其中的一部分,60x60。这是一个“a”方法的示例,但我正在寻找指向执行此操作的最高性能
我有一个接受 UIImage 的类,用它初始化一个 CIImage,如下所示: workingImage = CIImage.init(image: baseImage!) 然后使用图像以 3x3 的
我正在尝试显示来自 mysql 数据库的图像。有些图像显示正确,但有些图像在底部显示为剪切/裁剪,裁剪部分仅显示为空白,当它成为图像的一部分时,您真的无法摆脱。 CSS 无法解决这个问题,使用 ima
我有个问题。我有什么理由不应该使用这个 Intent: Intent intent = new Intent("com.android.camera.action.CROP"); 为了裁剪我刚刚拍摄的
我有一些代码可以调整图像大小,因此我可以获得图像中心的缩放 block - 我使用它来获取 UIImage 并返回一个小的方形表示图片,类似于在照片应用程序的相册 View 中看到的内容。 (我知道我
我是一名优秀的程序员,十分优秀!