代码之家  ›  专栏  ›  技术社区  ›  Sweeper

如何在不消除锯齿的情况下调整ui图像的大小?

  •  2
  • Sweeper  · 技术社区  · 6 年前

    我正在开发一款iOS棋盘游戏。我想给这块木板一种“纹理”。

    我所做的是创建了一个非常小的图像(非常小,一定要仔细看):。

    我将此图像传递给了 uicolor.init(patternimage:) initializer to create a uicolor that is this image.我用这个 uicolor 来填充一些正方形 uibezierpath s,结果如下:

    所有的复制品都完美地排成一条直线,形成许多对角线和直线。到目前为止还不错。

    现在在iPad上,我画的正方形会更大,这些正方形的边界也会更大。我已经成功地计算了方块的笔画宽度和大小,因此这不是问题。

    然而,由于iPad上的正方形更大,所以每个正方形的对角线会更多。我不想那样。我需要将非常小的图像调整为更大的图像,大小取决于正方形的笔划宽度。具体来说,调整大小的图像的宽度应该是笔划宽度的两倍。

    我编写这个扩展来调整图像的大小,改编自 post :

    扩展uiimage{ func调整大小(towidth newwidth:cgfloat)->uiimage{ 让scale=newwidth/size.width 让newheight=size.height*比例 uigraphicsBeginImageContextWithOptions(cgSize(width:newWidth,height:newHeight),false,0) self.draw(in:cgrct(x:0,y:0,width:newwidth,height:newheight))。 让newimage=uigraphicsGetImageFromCurrentImageContext()。 uigraphicsEndImageContext()。 返回newimage! } }
    
    

    像这样称呼它:

    这是我用来画一个正方形的代码 让path=uibezierpath(rect:cgrect(原点:点(用于:位置(x,y)),大小:cgsize(宽度:平方长度,高度:平方长度))) uicolor.black.setstroke()。 path.linewidth=行程宽度 //这条线很重要! uicolor(patternImage:imageLiteral(资源名称:
    
    

    “texture”)。已调整大小(towidth:strokewidth*2)).setfill()。 路径.填充() 路径.stroke()。

    现在游戏板在iPhone上看起来像这样:

    你可能需要放大网页才能明白我的意思。董事会现在看起来非常难看。您可以看到图像的每个副本的“边框”。我不想要这个。不过,在iPad上,主板看起来不错。我怀疑只有当我缩小图像时才会发生这种情况。

    我想这可能是由于使用扩展时发生的抗锯齿。我发现这篇文章在图像视图中执行此操作,而在自定义的游戏板视图中执行此操作。后者的解决方案似乎与我使用的完全相同。

    如何在不消除锯齿的情况下调整大小?或者在更高的抽象层次上,我如何使我的董事会看起来漂亮?

    enter image description here

    我把这张照片传给UIColor.init(patternImage:)初始值设定项以创建UIColor就是这张照片。我用过这个ui颜色填满一些正方形UIBezierPath结果如下:

    enter image description here

    所有的复制品都完美地排成一条直线,形成许多对角线和直线。到现在为止,一直都还不错。

    现在在iPad上,我画的正方形会更大,这些正方形的边界也会更大。我已经成功地计算了笔画宽度和正方形的大小,所以这不是问题。

    然而,由于iPad上的正方形更大,所以每个正方形的对角线会更多。我不想那样。我需要将非常小的图像调整为更大的图像,大小取决于正方形的笔划宽度。具体来说,调整大小的图像的宽度应该是笔划宽度的两倍。

    我写了这个扩展来调整图像的大小,根据这个post以下内容:

    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: 
    

    “texture”)。已调整大小(towidth:strokewidth*2)).setfill()。 路径.填充() 路径.stroke())

    现在iPhone上的游戏板看起来像这样:

    enter image description here

    你可能需要放大网页才能明白我的意思。董事会现在看起来非常难看。您可以看到图像的每个副本的“边框”。我不想要这个。不过,在iPad上,主板看起来不错。我怀疑这只发生在我缩小图像的时候。

    我想这可能是由于使用扩展时发生的抗锯齿。我找到了this postthis post关于消除抗锯齿,但前者似乎在图像视图中执行此操作,而我在draw(_:)我的习惯方法GameBoardView.后者的解决方案似乎与我使用的完全相同。

    如何在不消除锯齿的情况下调整大小?或者在更高的抽象层次上,我如何使我的董事会看起来漂亮?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Fattie    6 年前
    类规则:uiview{
    
    覆盖func draw(rect:cgrect){
    
    设t:cgfloat=15//所需线条厚度
    设g:cgfloat=30//线间所需间隙
    设w=rect.size.width
    设h=rect.size.height
    
    guard let c=uigraphicsgetcurrentContext()其他返回
    c.设置笔划颜色(uicolor.orange.cgcolor)
    c.设定线宽度(t)
    
    变量P=—(W>H?W:H)-T
    而P<=W{
    
    c.移动(到:cgpoint(x:p-t,y:-t))。
    C.添加线(到:cg点(x:p+t+h,y:t+h))
    c.行程路径()
    P+=g+t+t
    }
    }
    }
    

    享受。

    请注意,显然,您会剪辑该视图。

    如果您想在屏幕上或以某种模式显示它们的数量,只需执行该操作即可。


    要剪辑到给定的矩形:

    上面的类只是将其绘制为“uiview的大小”。

    然而,通常情况下,您希望在视图中以不同的坐标实际绘制一些“框”。(日历就是一个很好的例子)。

    此外,此示例显式地绘制“两条条纹”,而不是在背景色上绘制一条条纹:

    func simpleStripes(x:cgfloat,y:cgfloat,width:cgfloat,height:cgfloat){
    
    让stripewidth:cgfloat=20.0//无论您想要什么
    设m=stripewidth/2.0
    
    guard let c=uigraphicsgetcurrentContext()其他返回
    c.setLinewidth(条纹宽度)
    
    设r=cgrct(x:x,y:y,width:width,height:height)
    让longerside=width>height?宽度:高度
    
    c.存储状态()
    C.夹子(至:R)
    
    变量p=x-长边
    而P<=X+宽度{
    
    C.设置行程颜色(浅蓝色)
    c.移动(到:cgpoint(x:p-m,y:y-m))。
    C.添加线(到:cg点(x:p+m+高度,y:y+m+高度)
    c.行程路径()
    
    P+=条纹宽度
    
    C.设置行程颜色(浅灰色)
    c.移动(到:cgpoint(x:p-m,y:y-m))。
    C.添加线(到:cg点(x:p+m+高度,y:y+m+高度)
    c.行程路径()
    
    P+=条纹宽度
    }
    
    C.还原状态()
    }
    

    享受吧。

    请注意,很明显,您将剪切该视图。

    如果你想在屏幕上或者以一种模式显示它们的数量,就这么做。


    要剪切到给定的矩形:

    上面的类只是将其绘制为“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()
    }
    
        2
  •  1
  •   Tm Goyani    6 年前
    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!
        }
    }