#ios #swift #core-graphics #cgcontext
#iOS #swift #ядро-графика #cgcontext
Вопрос:
У меня есть два представления изображений, одно с изображением, другое с изображением, определенным с помощью методов CGContext, оба с одинаковым размером изображения и размером представления изображения друг над другом. В раскадровке я могу установить для обоих видов изображений значение «Подгонка по аспекту», чтобы пользователи на разных устройствах все еще могли видеть изображение. Однако, когда я иду рисовать что-то на наложенном втором представлении изображения, оно не масштабируется соответствующим образом (или относительно первого представления изображения, даже если они имеют одинаковый размер). Как мне добиться того, чтобы второе изображение в наложенном изображении отображалось в том же масштабе, что и изображение ниже?
Пример кода:
import CoreGraphics
import UIKit
class Map: UIViewController, UIScrollViewDelegate {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var drawnImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.minimumZoomScale = 1.0
self.scrollView.maximumZoomScale = 6.0
let data = grabData()
print(data!)
var img = UIImage(named: "floor1")
print(img!.size)
imageView.image = img
img = draw(imageView.bounds.size, data: data!)
print(img!.size)
drawnImageView.image = img
for c in drawnImageView.constraints {
if c.identifier == "constraintImageHeight" {
c.constant = img!.size.height * drawnImageView.bounds.width / img!.size.width;
break;
}
}
}
}
func draw(img: UIImage) -> UIImage {
UIGraphicsBeginImageContext(img.size)
let context = UIGraphicsGetCurrentContext()
// Drawing
let color = UIColor(red: 0.67, green: 0.4, blue: 0.56, alpha: 1)
CGContextSetStrokeColorWithColor(context, color.CGColor)
CGContextSetLineWidth(context, 2.0)
var y = 0
for _ in 0..<100 {
let b = CGRect(origin: CGPoint(x: 0, y: y), size: CGSize(width: 1200, height: 1))
CGContextStrokeRect(context, b)
y = 30
}
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
Обновление 1:
(заменить после ‘// Drawing’) Если вы загружаетесь с помощью симулятора iPhone 5, он не отображается в том же месте по отношению к фотографии, что и в симуляторе iPhone 6.
func draw(size: CGSize, data: [TotalLine]) -> UIImage {
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()
let screen: CGRect = UIScreen.mainScreen().bounds
let x = screen.size.width, y = screen.size.height
// Drawing
//let color = UIColor(red: 0.67, green: 0.4, blue: 0.56, alpha: 1)
let color = UIColor.redColor()
CGContextSetStrokeColorWithColor(context, color.CGColor)
CGContextSetLineWidth(context, 2.0)
let line = CGRect(origin: CGPoint(x: (x/16), y: (y*0.502)), size: CGSize(width: (x/20), height: 2))
CGContextStrokeRect(context, line)
let test = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: x, height: y))
CGContextStrokeRect(context, test)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
Обновление 2:
iPhone 6:
iPhone 5:
Я хочу, чтобы эта красная линия отображалась между комнатами, как на скриншоте iPhone 6. В iPhone 5 он немного ниже.
Обновление 3:
Печать представлений изображений:
iPhone 5:
Просмотр нарисованного изображения: кадр = (0 0; 600 536); Просмотр изображения: кадр = (0 0; 600 536);
iPhone 6:
Просмотр нарисованного изображения: кадр = (0 0; 600 536); Просмотр изображения: кадр = (0 0; 600 536);
Комментарии:
1. Что есть
x
иy
в вашем udpated коде? не указаны определения и начальные значения. Выfor
вообще удалили цикл? Что именно не так на iPhone 5 по сравнению с iPhone 6?2. распечатайте фрейм ImageView для обоих устройств прямо перед вызовом
draw
метода и предоставьте вывод здесь3. Обновлено в вопросе, обновление 3
4. @alexburtnik есть идеи, что происходит?
5. Я думал об этом, но пока нет идей, и я не могу воспроизвести, если, к сожалению. Если у вас есть тестовый проект с этой проблемой, просто поделитесь им со мной, и я, вероятно, исправлю это
Ответ №1:
Попробуйте заменить эту строку:
UIGraphicsBeginImageContext(img.size)
с этим:
UIGraphicsBeginImageContextWithOptions(img.size, false, UIScreen.main.scale)
Непонятно, почему вы используете 100 и 1200 закодированных значений. если исходное изображение достаточно большое (выше 3000 или шире 1200), ваши строки не будут заполнять все изображение. Кроме того, на самом деле вам не нужно исходное изображение для создания наложения. Вам просто нужно знать размер, не так ли? Вместо этого попробуйте этот метод:
func createLinesImage(size: CGSize) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
let context = UIGraphicsGetCurrentContext()!
let color = UIColor(red: 0.67, green: 0.4, blue: 0.56, alpha: 1)
context.setStrokeColor(color.cgColor)
context.setLineWidth(2.0)
var y = CGFloat(0)
while y < size.height {
let lineRect = CGRect(x: 0, y: y, width: size.width, height: 1)
context.stroke(lineRect)
y = 30
}
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
Теперь, если вы хотите рисовать линии только по исходному изображению, вызовите свой метод следующим образом:
imageView2.image = createLinesImage(size: originalImage.size)
Если вам нужно заполнить весь вид изображения линиями, даже если для исходного изображения есть пустые зоны, используйте эту строку:
imageView2.image = createLinesImage(size: imageView2.bounds.size)
Комментарии:
1. В UIScreen нет элемента «main»
2. Используете ли вы swift 2? Попробуйте UIScreen.MainScreen().затем масштабируйте
3. Не работает. Все, что он в конечном итоге делает, это перемещает нарисованное изображение на несколько сотен пикселей…
4. Было бы здорово, если бы вы добавили скриншот своей проблемы. Я попробовал ваш код, и он выглядит так же, как вы его реализуете. Исходное изображение ниже и программно созданное изображение над ним, которое содержит кучу горизонтальных линий. Это действительно то, чего вы ожидаете? snag.gy/j6woR3.jpg
5. Да, я просто вставил горизонтальные линии, чтобы было легче просматривать изменения. По сути, это система отображения для помещений, я должен рисовать линии в коридорах здания. (тот же код, что и раньше) pasteboard.co/e9vmls8T2.png