Как изменить размер UIImage без сглаживания? - PullRequest
0 голосов
/ 05 июля 2018

Я занимаюсь разработкой настольной игры для iOS. Я пытаюсь придать доске своего рода «текстуру».

Я создал это очень маленькое изображение (очень маленькое, обязательно внимательно):

enter image description here

И я передал это изображение инициализатору UIColor.init(patternImage:), чтобы создать UIColor, то есть это изображение. Я использовал это UIColor, чтобы заполнить квадрат UIBezierPath с, и результат выглядит так:

enter image description here

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

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

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

Я написал это расширение, чтобы изменить размер изображения, адаптированный из этого поста :

extension UIImage {
    func resized(toWidth newWidth: CGFloat) -> UIImage {

        let scale = newWidth / size.width
        let newHeight = size.height * scale
        UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: newHeight), false, 0)
        self.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage!
    }
}

И назвал это так:

// this is the code I used to draw a single square
let path = UIBezierPath(rect: CGRect(origin: point(for: Position(x, y)), size: CGSize(width: squareLength, height: squareLength)))
UIColor.black.setStroke()
path.lineWidth = strokeWidth
// this is the line that's important!
UIColor(patternImage: #imageLiteral(resourceName: 

"текстура"). Resized (toWidth: strokeWidth * 2)). SetFill () path.fill () path.stroke ()

Теперь игровое поле на iPhone выглядит следующим образом:

enter image description here

Возможно, вам придется немного увеличить масштаб веб-страницы, чтобы понять, что я имею в виду. Доска теперь выглядит крайне некрасиво. Вы можете увидеть «границы» каждой копии изображения. Я не хочу этого Хотя на iPad плата выглядит хорошо. Я подозреваю, что это происходит только тогда, когда я уменьшаю размер изображения.

Я подумал, что это может быть связано с сглаживанием, которое происходит, когда я использую расширение. Я нашел этот пост и этот пост об удалении сглаживания, но первый, кажется, делает это в виде изображения, в то время как я делаю это в методе draw(_:) моего пользовательского GameBoardView. Решение последнего похоже на то, что я использую.

Как я могу изменить размер без сглаживания? Или на более высоком уровне абстракции, как я могу сделать мою доску красивой?

Ответы [ 2 ]

0 голосов
/ 07 августа 2018
extension UIImage {

    func ResizeImage(targetSize: CGSize) -> UIImage
    {
        let size = self.size

        let widthRatio  = targetSize.width  / self.size.width
        let heightRatio = targetSize.height / self.size.height

        // Figure out what our orientation is, and use that to form the rectangle
        var newSize: CGSize
        if(widthRatio > heightRatio) {
            newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
        } else {
            newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
        }
        // This is the rect that we've calculated out and this is what is actually used below
        let rect = CGRect(x: 0, y: 0, width: newSize.width,height: newSize.height)

        // Actually do the resizing to the rect using the ImageContext stuff
        UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
        self.draw(in: rect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage!
    }
}
0 голосов
/ 06 августа 2018
class Ruled: UIView {

    override func draw(_ rect: CGRect) {

        let T: CGFloat = 15     // desired thickness of lines
        let G: CGFloat = 30     // desired gap between lines
        let W = rect.size.width
        let H = rect.size.height

        guard let c = UIGraphicsGetCurrentContext() else { return }
        c.setStrokeColor(UIColor.orange.cgColor)
        c.setLineWidth(T)

        var p = -(W > H ? W : H) - T
        while p <= W {

            c.move( to: CGPoint(x: p-T, y: -T) )
            c.addLine( to: CGPoint(x: p+T+H, y: T+H) )
            c.strokePath()
            p += G + T + T
        }
    }
}

Наслаждайтесь.

Обратите внимание, что вы, очевидно, обрезаете это представление.

Если вы хотите, чтобы их было несколько на экране или в шаблоне, просто сделайте это.


Чтобы обрезать данный прямоугольник:

Класс, приведенный выше, просто рисует его как "размер UIView".

Однако часто вы хотите нарисовать несколько «прямоугольников» на самом деле в представлении в разных координатах. (Хороший пример для календаря).

enter image description here

Кроме того, этот пример явно рисует "обе полосы", а не рисует одну полосу поверх цвета фона:

func simpleStripes(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) {

    let stripeWidth: CGFloat = 20.0 // whatever you want
    let m = stripeWidth / 2.0

    guard let c = UIGraphicsGetCurrentContext() else { return }
    c.setLineWidth(stripeWidth)

    let r = CGRect(x: x, y: y, width: width, height: height)
    let longerSide = width > height ? width : height

    c.saveGState()
    c.clip(to: r)

        var p = x - longerSide
        while p <= x + width {

            c.setStrokeColor(pale blue)
            c.move( to: CGPoint(x: p-m, y: y-m) )
            c.addLine( to: CGPoint(x: p+m+height, y: y+m+height) )
            c.strokePath()

            p += stripeWidth

            c.setStrokeColor(pale gray)
            c.move( to: CGPoint(x: p-m, y: y-m) )
            c.addLine( to: CGPoint(x: p+m+height, y: y+m+height) )
            c.strokePath()

            p += stripeWidth
        }

    c.restoreGState()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...