为什么在SwiftUI中调整大小的PDF会产生锐利的边缘? [英] Why do PDFs resized in SwiftUI getting sharp edges?

查看:137
本文介绍了为什么在SwiftUI中调整大小的PDF会产生锐利的边缘?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用Xcode 11.4和iOS 13.4在启用SwiftUI的应用程序中包含pdf.但是,当我调整pdf大小时,它会出现卷曲的边缘.我提供了两个版本的pdf:一个大pdf(icon.pdf)和一个小pdf(icon_small.pdf).当我调整icon.pdf的大小时,它会得到开始边缘,而icon_small.pdf时会得到平滑的边缘.这个问题也适用于我尝试过的所有其他PDF.

I try to include a pdf in my SwiftUI enabled app using Xcode 11.4 and iOS 13.4. However, when I resize the pdf, it gets crips edges. I have included two versions of the pdf: One large pdf (icon.pdf) and one small pdf (icon_small.pdf). When I resize icon.pdf it gets start edges, while icon_small.pdf gets smooth edges. The issue applies to all other pdfs I have tried as well.

这是我的代码:

struct ContentView: View {
    var body: some View {
        VStack {
            Spacer()
            Text("icon.pdf:")
            Image("icon")
                .resizable()
                .renderingMode(.template)
                .aspectRatio(contentMode: .fit)
                .frame(width: 27.0, height: 27.0)
            Spacer()
            Text("icon_small.pdf:")
            Image("icon_small")
            Spacer()
        }
    }
}

icon.pdficon_small.pdf都具有以下资产设置:

Both icon.pdf and icon_small.pdf have the following asset settings:

  • 渲染为:模板图像
  • 调整大小:保留矢量数据
  • 设备:通用
  • 秤:单秤

可在此处找到pdf文件:

The pdfs are available here:

  • http://simensolbakken.com/public/stackoverflow/icon.pdf
  • http://simensolbakken.com/public/stackoverflow/icon_small.pdf

推荐答案

我使用您提供的图像对两个矢量图像进行了并排比较:

I did a side by side comparison for both vector images using the ones you provided:

  • http://simensolbakken.com/public/stackoverflow/icon.pdf
  • http://simensolbakken.com/public/stackoverflow/icon_small.pdf

起初,我使用了SwiftUI的内置Image,并且如上所述,它们在极端情况下的表现都很差:

At first, I used SwiftUI's inbuilt Image and as mentioned, both performed badly at their extreme ends:

  • 按比例缩小大图像时会出现锐利的边缘
  • 小图像在放大时变得模糊

起初我以为可能是您的pdf矢量,所以我使用了我知道在以前的项目中效果很好的矢量,但是我遇到了同样的问题.
认为这是一个UIImage问题,我使用了SwiftUIImage(uiImage:)但同样的问题.

At first I thought it might be your pdf vectors so I used ones that I know have worked well in my previous projects, but I got the same issues.
Thinking it to be a UIImage issue, I used SwiftUIs Image(uiImage:) but same problem.

最后一个猜测是图像容器,并且知道UIImageView可以很好地处理矢量图像,因此使UIViewRepresentable包裹UIImageView似乎可以解决此问题.现在看来,这可能是一种解决方法.

Last guess was the image container, and knowing that UIImageView has handled vector images well, getting UIViewRepresentable to wrap the UIImageView seems to solve this issue. And for now it looks like a possible workaround.

struct MyImageView: UIViewRepresentable {
  var name: String
  var contentMode: UIView.ContentMode = .scaleAspectFit
  var tintColor: UIColor = .black

  func makeUIView(context: Context) -> UIImageView {
    let imageView = UIImageView()
    imageView.setContentCompressionResistancePriority(.fittingSizeLevel, 
                                                      for: .vertical)
    return imageView
  }

  func updateUIView(_ uiView: UIImageView, context: Context) {
    uiView.contentMode = contentMode
    uiView.tintColor = tintColor
    if let image = UIImage(named: name) {
      uiView.image = image
    }
  }
}

这会丢失一些SwiftUI Image修饰符(您仍然具有普通的View修饰符),但是您始终可以像上面所示那样传入某些参数,例如contentModetintColor.如果需要,添加更多并进行相应处理.

This loses some SwiftUI Image modifiers (you still have normal View modifiers) but you can always pass in some parameters such as contentMode and tintColor as shown above. Add more if needed and handle accordingly.

struct ContentView: View {
  var body: some View {
    VStack {
      MyImageView(name: "icon", //REQUIRED
                  contentMode: .scaleAspectFit, //OPTIONAL
                  tintColor: .black /*OPTIONAL*/)
        .frame(width: 27, height: 27)
      MyImageView(name: "icon_small", //REQUIRED
                  contentMode: .scaleAspectFit, //OPTIONAL
                  tintColor: .black /*OPTIONAL*/)
        .frame(width: 27, height: 27)
    }
  }
}


现在所有这些都是推测,但看起来SwiftUI似乎将矢量图像视为PNG.


Now this is all speculation but it looks as though SwiftUI treats vector images as a PNG.

下面的示例是对UIKitUIImageViewSwiftUIImage中呈现的大小矢量图像的简单并排比较.

The following example is a simple side by side comparison of the small and large vector images rendered in UIKit's UIImageView and SwiftUI's Image.

struct ContentView: View {
  let (largeImage, smallImage) = ("icon", "icon_small")
  let range = stride(from: 20, to: 320, by: 40).map { CGFloat($0) }

  var body: some View {
    List(range, id: \.self) { (side) in
      ScrollView(.horizontal) {
        VStack(alignment: .leading) {
          Text(String(format: "%gx%g", side, side))
          HStack {
            VStack {
              Text("UIKit")
              MyImageView(name: self.smallImage)
                .frame(width: side, height: side)
              MyImageView(name: self.largeImage)
                .frame(width: side, height: side)
            }
            VStack {
              Text("SwiftUI")
              Image(self.smallImage)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: side)
              Image(self.largeImage)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: side)
            }
          }
        }
      }
    }
  }
}

结果:

  1. 第一行;左:UIImageView
  2. 中的小图像
  3. 第一行;右:SwiftUI Image
  4. 中的小图片
  5. 底行;左:UIImageView
  6. 中的大图像
  7. 底行;右:SwiftUI Image
  8. 中的大图像
  1. Top row; Left : Small Image in UIImageView
  2. Top row; Right : Small Image in SwiftUI Image
  3. Bottom row; Left : Large Image in UIImageView
  4. Bottom row; Right : Large Image in SwiftUI Image

UIKitUIImageView具有一致的性能,而SwiftUIImage遇到问题.

UIKit's UIImageView has consistent performace while SwiftUI's Image is having trouble.

这篇关于为什么在SwiftUI中调整大小的PDF会产生锐利的边缘?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆