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


177

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

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

답변:


351

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

  1. 이미지를 적절한 @ 1x 크기 (예 : 툴바 버튼의 경우 24x24).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.pdf44x44 벡터 자산 인 것이 있다고 가정합니다 . 에서 빌드시 다음과 같은 파일을 생성합니다 :

  • foo@1x.png 44x44에서
  • foo@2x.png 88x88에서
  • foo@3x.png 132x132에서

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

  • bar@1x.png 100x100에서
  • bar@2x.png 200x200에서
  • bar@3x.png 300x300에서

시사점 :

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

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

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

8
좋은 글씨. 이에 대한 내용은 2014 WWDC 세션 411- "인터페이스 빌더의 새로운 기능"(44:13)에 설명되어 있습니다. 래스터 화는 빌드 타임에 완료된다고합니다. 또한 흥미롭게도 MAC에서는 런타임에 벡터를 사용합니다. 미래의 먼 시점에서 iOS도 마찬가지입니다.
Mike Vosseller

15
불행히도 슬라이스 값의 크기를 조정하지 않습니다. 따라서 5에서 모서리를 슬라이스하면 2x 및 3x 이미지의 경우 10 및 15로 크기가 조정되지 않습니다.
Jesse

5
@Jesse 슬라이스 값을 스케일링하려면 슬라이스 값을 사용 resizableImageWithCapInsets:하고 다음과 같이 나누어 코드에서 직접 할 수 있습니다.[UIScreen mainScreen].scale
Arie Litovsky

1
슬라이스에 @ArieLitovsky 제안을 명확히하기 위해 : 당신이해야 자산에서 슬라이스를 제거 하고 코드로 이동, 같은CGFloat scale = [UIScreen mainScreen].scale; UIImage *image = [[UIImage imageNamed:@"my_unsliced_asset"] resizableImageWithCapInsets:UIEdgeInsetsMake(10 * scale, 11 * scale, 12 * scale, 13 * scale)];
glyuck

6
XCode 8에서 어떻게해야합니까? 옵션이 사라진 것 같습니다!
제랄드

26

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


15

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

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

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

Inkscape에서 :

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

노트:

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

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

추가 자료


12

여전히 업데이트하지 않은 사람들을 위해 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에서는 답변에 설명 된 오래된 스케일링 메커니즘이 사용됩니다.


1

프로젝트 내에서 일반적인 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
        }
    }

}

1
나는 이것을 시도했지만 이미지를 더 큰 픽셀 크기로 스케일링하는 것처럼 보이지 않습니까? 내가 얻는 UIImage 자체는 올바른 크기입니다. 단지 벡터 이미지가 PDF의 원래 픽셀 크기에 중심을두고 있다는 것입니다. (UIImage 크기로 크기를 조정하고 싶었습니다.) 이것이 가능한지 알고 있습니까?
DivideByZer0
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.