[xcode] Xcode에서 벡터 이미지는 어떻게 작동합니까 (예 : pdf 파일)?

Xcode 6에서 벡터 지원은 어떻게 작동합니까?

이미지 크기를 조정하려고하면 들쭉날쭉 해 보입니다.



답변

Xcode에서 벡터를 사용하는 방법 (7 및 6.3+) :

  1. 이미지를 적절한 @ 1x 크기 (예 : 툴바 버튼의 경우 24×24).pdf 파일 로 저장하십시오 .
  2. 당신에 Images.xcassets 파일, 새로 만들기 이미지 설정을 .
  3. (가)에서 속성을 속성 의 설정 규모 요인단일 벡터 .
  4. pdf 파일을 모든 범용 섹션 으로 끌어다 놓습니다 .
  5. 이제 .png 파일 과 마찬가지로 이름으로 이미지를 참조 할 수 있습니다 .

    UIImage(named: "myImage")

이전 버전의 Xcode (6.0-6.2)에서 벡터를 사용하는 방법 :

  • 3 단계를 제외하고 위의 단계를 수행하여 유형벡터로 설정하십시오 .

Xcode에서 벡터가 작동하는 방식

대부분의 사람들이 벡터를 생각할 때 확대 및 축소 할 수있는 이미지를 생각하기 때문에 Xcode에서는 벡터 지원이 혼동됩니다. 그러나 Xcode 6 및 7은 iOS를 완전히 지원하지 않으므로 약간 다르게 작동합니다.

벡터 시스템은 정말 간단 합니다. 그것은 당신의 소요 .pdf이미지를, 그리고 생성 @1x.png, @2x.png@3x.png에서 자산 빌드 시간 . (당신은 할 수 Assets.car의 내용을 검사하는 도구를 사용하여 이를 확인할 수 있습니다.)

예를 들어 foo.pdf44×44 벡터 자산 인 것이 있다고 가정합니다 . 에서 빌드시 다음과 같은 파일을 생성합니다 :

  • foo@1x.png 44×44에서
  • foo@2x.png 88×88에서
  • foo@3x.png 132×132에서

이것은 모든 크기의 이미지에서 동일하게 작동합니다. 예를 들어 bar.pdf100×100 인 경우 다음과 같은 결과가 나타납니다.

  • bar@1x.png 100×100에서
  • bar@2x.png 200×200에서
  • bar@3x.png 300×300에서

시사점 :

  • 이미지의 새 크기를 선택할 수 없습니다 . 44×44 크기로 유지하면 좋을 것입니다. 그 이유는 완전한 벡터 지원이 구현되지 않았기 때문입니다 . 이 벡터가하는 유일한 일은 이미지 자산을 저장하는 시간을 절약하는 것입니다. 이미 1 단계 프로세스로 만드는 도구 (예 : Photoshop 스크립트)가있는 경우 pdf 벡터를 사용하여 얻을 수있는 유일한 것은 미래 보장 지원입니다 (예 : iOS 9 Apple에서 @ 4x 자산이 필요한 경우, 이것들은 작동합니다.) 유지 해야 할 파일 수가 적습니다 .
  • PDF 파일로 저장된 @ 1x 크기의 모든 자산을 요청해야합니다 . 무엇보다도 UIImageViews는 정확한 내장 컨텐츠 크기를 가질 수 있습니다.

왜 이런 식으로 작동합니까?

  • 이것은하게 호환 이전의 iOS 버전.
  • 벡터 크기 조정은 런타임에 계산 집약적 인 작업 일 수 있습니다. 이 방법으로 구현하면 성능 저하가 없습니다 .

답변

Xcode 8에서는 PDF를 추가하고 새 이미지 세트를 생성 한 다음 속성 관리자에서 스케일을 단일 스케일로 옵션을 설정할 수 있습니다.
여기에 이미지 설명을 입력하십시오


답변

이것은 @Senseful의 탁월한 답변을 보완하는 것입니다.

.pdf 형식으로 벡터 이미지를 만드는 방법

무료이며 오픈 소스이지만 다른 프로그램도 비슷해야하므로 Inkscape에서이 작업을 수행하는 방법을 알려 드리겠습니다.

Inkscape에서 :

  1. 새 프로젝트를 작성하십시오.
  2. 파일> 문서 속성으로 이동하여 사용자 정의 페이지 크기를 @ 1x 크기 (44×44, 100×100 등)로 단위를 px 단위로 설정하십시오.
  3. 작품을 만드십시오.
  4. 파일> 다른 이름으로 저장 …> 인쇄 가능한 문서 형식 (* .pdf)> 저장> 확인으로 이동하십시오. 또는 인쇄> 파일로 인쇄> 출력 형식 : PDF> 인쇄로 이동할 수 있지만 많은 옵션이 없습니다.

노트:

  • 허용 된 답변에서 언급했듯이 Xcode는 여전히 빌드 타임에 래스터 화 된 이미지를 생성하므로 이미지 크기를 조정할 수 없습니다. 이미지 크기를 조정해야하는 경우 크기가 다른 새 .pdf 파일을 만들어야합니다.
  • 잘못된 페이지 크기 인 .svg 이미지가 이미있는 경우 다음을 수행하십시오.

    1. 페이지 크기 변경 (Inkscape> 파일> 문서 속성)
    2. 작업 공간에서 모든 객체 (Ctrl + A)를 선택하고 새 페이지 크기에 맞게 크기를 조정하십시오. 가로 세로 크기를 유지하려면 Ctrl 키를 누르고 있습니다.
  • .svg 파일을 .pdf로 변환하려면 온라인 유틸리티를 사용하여 작업을 수행 할 수도 있습니다. 다음은 이 답변의 입니다 . 이는 .pdf 크기를 쉽게 설정할 수 있다는 이점이 있습니다.

추가 자료


답변

여전히 업데이트하지 않은 사람들을 위해 Xcode 9 (iOS 11)에 변경 사항이있었습니다.

Cocoa Touch의 새로운 기능 (WWDC 2017 세션 201) (@ 32:55)
https://developer.apple.com/videos/play/wwdc2017/201/

간단히 말해 Asset Catalog에는 속성 벡터에 “벡터 데이터 유지”라는 새로운 확인란이 포함됩니다. 이 옵션을 선택하면 PDF 데이터가 컴파일 된 바이너리에 포함되어 물론 크기가 커집니다. 그러나 iOS가 벡터 데이터를 양방향으로 확장하고 멋진 이미지를 제공 할 수있는 기회를 제공합니다 (자체 어려움이 있음). 11 미만의 iOS에서는 답변에 설명 된 오래된 스케일링 메커니즘이 사용됩니다.


답변

프로젝트 내에서 일반적인 PDF 파일을 벡터 이미지로 사용하고이 확장명을 사용하여 모든 크기의 이미지를 렌더링 할 수 있습니다. iOS는 PDF 파일에서 .PNG 이미지를 생성하지 않으며 원하는 크기로 이미지를 렌더링 할 수 있기 때문에이 방법이 더 좋습니다.

    extension UIImage {

    static func fromPDF(filename: String, size: CGSize) -> UIImage? {
        guard let path = Bundle.main.path(forResource: filename, ofType: "pdf") else { return nil }
        let url = URL(fileURLWithPath: path)
        guard let document = CGPDFDocument(url as CFURL) else { return nil }
        guard let page = document.page(at: 1) else { return nil }

        let imageRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        if #available(iOS 10.0, *) {
            let renderer = UIGraphicsImageRenderer(size: size)
            let img = renderer.image { ctx in
                UIColor.white.withAlphaComponent(0).set()
                ctx.fill(imageRect)
                ctx.cgContext.translateBy(x: 0, y: size.height)
                ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
                ctx.cgContext.concatenate(page.getDrawingTransform(.artBox, rect: imageRect, rotate: 0, preserveAspectRatio: true))
                ctx.cgContext.drawPDFPage(page);
            }

            return img
        } else {
            // Fallback on earlier versions
            UIGraphicsBeginImageContextWithOptions(size, false, 2.0)
            if let context = UIGraphicsGetCurrentContext() {
                context.interpolationQuality = .high
                context.setAllowsAntialiasing(true)
                context.setShouldAntialias(true)
                context.setFillColor(red: 1, green: 1, blue: 1, alpha: 0)
                context.fill(imageRect)
                context.saveGState()
                context.translateBy(x: 0.0, y: size.height)
                context.scaleBy(x: 1.0, y: -1.0)
                context.concatenate(page.getDrawingTransform(.cropBox, rect: imageRect, rotate: 0, preserveAspectRatio: true))
                context.drawPDFPage(page)
                let image = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return image
            }
            return nil
        }
    }

}


답변