Làm thế nào để hình ảnh vector hoạt động trong Xcode (tức là tệp pdf)?


176

Làm thế nào để hỗ trợ vector hoạt động trong Xcode 6?

Khi tôi thử thay đổi kích thước một hình ảnh, nó trông lởm chởm, những gì mang lại?

Câu trả lời:


351

Cách sử dụng vectơ trong Xcode (7 và 6.3+):

  1. Lưu hình ảnh dưới dạng tệp .pdf ở kích thước @ 1x thích hợp (ví dụ 24x24 cho nút thanh công cụ ).
  2. Trong tệp Images.xcassets của bạn , tạo Bộ ảnh mới .
  3. Trong Attributes Inspector , thiết lập các yếu tố Scale để đơn Vector .
  4. Kéo và thả tệp pdf của bạn vào phần Tất cả, Phổ quát .
  5. Bây giờ bạn có thể tham chiếu hình ảnh của mình theo tên của nó, giống như bất kỳ tệp .png nào .

    UIImage(named: "myImage")

Cách sử dụng vectơ trong các phiên bản Xcode cũ hơn (6.0 - 6.2):

  • Thực hiện theo các bước trên, ngoại trừ bước 3, đặt Loại thành Vectơ .

Các vectơ hoạt động như thế nào trong Xcode

Hỗ trợ vectơ khó hiểu trong Xcode, bởi vì khi hầu hết mọi người nghĩ về vectơ, họ nghĩ về hình ảnh có thể mở rộng lên xuống mà vẫn trông đẹp. Tuy nhiên, Xcode 6 và 7 không có hỗ trợ vector đầy đủ cho iOS, vì vậy mọi thứ hoạt động hơi khác một chút.

Hệ thống vector thực sự đơn giản . Phải mất của bạn .pdfhình ảnh, và tạo ra @1x.png, @2x.png@3x.pngtài sản tại thời gian xây dựng . (Bạn có thể sử dụng một công cụ để kiểm tra nội dung của Assets.car để xác minh điều này.)

Ví dụ: giả sử bạn được cho foo.pdflà tài sản vectơ 44x44. Tại thời điểm xây dựng, nó sẽ tạo ra các tệp sau:

  • foo@1x.png tại 44x44
  • foo@2x.png tại 88x88
  • foo@3x.png ở 132x132

Điều này hoạt động tương tự cho bất kỳ hình ảnh kích thước. Ví dụ: nếu bạn có bar.pdf100x100, bạn sẽ nhận được:

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

Hàm ý:

  • Bạn không thể chọn kích thước mới cho hình ảnh ; nó sẽ chỉ trông tốt nếu bạn giữ nó ở kích thước 44x44. Lý do là hỗ trợ vector đầy đủ không được thực hiện . Điều duy nhất các vectơ này làm là giúp bạn tiết kiệm thời gian lưu tài sản hình ảnh của bạn. Nếu bạn có một công cụ (ví dụ: tập lệnh Photoshop) đã thực hiện quy trình một bước này, điều duy nhất bạn sẽ đạt được bằng cách sử dụng vectơ pdf là hỗ trợ bằng chứng trong tương lai (ví dụ: nếu trong iOS 9, Apple bắt đầu yêu cầu tài sản @ 4x, những thứ này sẽ chỉ hoạt động) và bạn sẽ có ít tệp hơn để duy trì .
  • Bạn nên yêu cầu tất cả tài sản của mình ở kích thước @ 1x, được lưu dưới dạng tệp PDF . Trong số những thứ khác, điều này sẽ cho phép UIImageViews có kích thước nội dung chính xác.

Tại sao nó (có thể) hoạt động theo cách này:

  • Điều này làm cho nó tương thích ngược với các phiên bản iOS trước.
  • Thay đổi kích thước vectơ có thể là một nhiệm vụ chuyên sâu tính toán trong thời gian chạy; bằng cách thực hiện theo cách này, không có lượt truy cập hiệu suất .

8
Đẹp viết lên. Điều này được thảo luận trong Phiên WWDC 2014 2014 - "Có gì mới trong Trình tạo giao diện" tại thời điểm 44:13. Lưu ý rằng họ nói rằng việc rasterization được thực hiện tại thời điểm xây dựng. Cũng thú vị trên MAC, nó sẽ sử dụng các vectơ khi chạy. Tại một số điểm xa trong tương lai hy vọng iOS cũng sẽ như vậy.
Mike Vosseller

15
Thật không may, nó không mở rộng các giá trị lát. Vì vậy, nếu bạn cắt góc ở 5, nó sẽ không chia tỷ lệ thành 10 và 15 cho hình ảnh 2x và 3x.
Jesse

5
@Jlie nếu bạn muốn chia tỷ lệ các giá trị lát, bạn có thể tự thực hiện mã bằng cách sử dụng resizableImageWithCapInsets:và chia các giá trị lát của mình cho[UIScreen mainScreen].scale
Arie Litovsky

1
Để làm rõ đề xuất @ArieLitovsky về việc cắt lát: bạn nên xóa phần cắt ra khỏi tài sản và chuyển nó sang mã, đại loại nhưCGFloat scale = [UIScreen mainScreen].scale; UIImage *image = [[UIImage imageNamed:@"my_unsliced_asset"] resizableImageWithCapInsets:UIEdgeInsetsMake(10 * scale, 11 * scale, 12 * scale, 13 * scale)];
glyuck

6
Làm thế nào để tôi làm điều này cho XCode 8? tùy chọn dường như đã biến mất!
Gerald

26

Trong Xcode 8, bạn vẫn có thể thêm pdf, tạo Bộ ảnh mới và trong Trình theo dõi thuộc tính, đặt tùy chọn Thang đo thành một tỷ lệ. nhập mô tả hình ảnh ở đây


15

Đây là phần bổ sung cho câu trả lời xuất sắc của @Senseful.

Cách tạo hình ảnh vector ở định dạng .pdf

Tôi sẽ nói làm thế nào để làm điều này trong Inkscape vì nó là nguồn mở và miễn phí nhưng các chương trình khác nên tương tự.

Trong Inkscape:

  1. Tạo một dự án mới.
  2. Chuyển đến Tệp> Thuộc tính Tài liệu và đặt kích thước trang tùy chỉnh thành kích thước @ 1x của bạn là (44x44, 100x100, v.v.) với các đơn vị tính bằng px.
  3. Làm tác phẩm nghệ thuật của bạn.
  4. Chuyển đến Tệp> Lưu dưới dạng ...> Định dạng Tài liệu có thể in (* .pdf)> Lưu> OK. (Ngoài ra, bạn có thể đi đến In> In thành tệp> Định dạng đầu ra: PDF> In nhưng không có nhiều tùy chọn.)

Ghi chú:

  • Như đã đề cập trong câu trả lời được chấp nhận, bạn không thể thay đổi kích thước hình ảnh của mình vì Xcode vẫn tạo ra hình ảnh rasterized khi xây dựng. Nếu bạn cần thay đổi kích thước hình ảnh của mình, bạn nên tạo một tệp .pdf mới với kích thước khác.
  • Nếu bạn đã có một hình ảnh .svg có kích thước trang sai, hãy làm như sau:

    1. Thay đổi kích thước trang (Inkscape> Tệp> Thuộc tính Tài liệu)
    2. Chọn tất cả các đối tượng (Ctrl + A) trên không gian làm việc và thay đổi kích thước chúng cho phù hợp với kích thước trang mới. (Giữ phím Ctrl để giữ kích thước khung hình.)
  • Để chuyển đổi tệp .svg thành .pdf, bạn cũng có thể tìm các tiện ích trực tuyến để thực hiện công việc cho mình. Đây là một ví dụ từ câu trả lời này . Điều này có lợi ích là cho phép bạn đặt kích thước .pdf dễ dàng.

đọc thêm


12

Đối với những người vẫn chưa được cập nhật, đã có thay đổi trong Xcode 9 (iOS 11).

Có gì mới trong Ca cao cảm ứng (Phiên WWDC 2017 201) (@ 32: 55) https://developer.apple.com/ideo/play/wwdc2017/201/

Nói một cách ngắn gọn, Danh mục tài sản hiện bao gồm hộp kiểm mới trong Trình kiểm tra thuộc tính có tên là Bảo tồn dữ liệu vectơ. Khi được chọn, dữ liệu PDF sẽ được đưa vào tệp nhị phân được biên dịch, tăng kích thước của khóa học. Nhưng nó mang lại cơ hội cho iOS mở rộng dữ liệu vectơ theo cả hai hướng và cung cấp hình ảnh đẹp. (Với những khó khăn riêng). Đối với iOS dưới 11, các cơ chế chia tỷ lệ cũ được mô tả trong câu trả lời trở lên được sử dụng.


1

Bạn có thể sử dụng các tệp PDF bình thường bên trong dự án của mình dưới dạng hình ảnh Vector và hiển thị hình ảnh có kích thước bất kỳ bằng cách sử dụng tiện ích mở rộng này. Cách này tốt hơn vì iOS sẽ không tạo hình ảnh .PNG từ các tệp PDF của bạn, ngoài ra bạn có thể hiển thị hình ảnh với bất kỳ kích thước nào bạn muốn:

    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
Tôi đã thử điều này, nhưng có vẻ như nó không chia tỷ lệ hình ảnh lên kích thước pixel lớn hơn? Bản thân UIImage mà tôi nhận được có kích thước chính xác; chỉ là hình ảnh vector được căn giữa và vẫn ở kích thước pixel gốc của PDF. (Tôi muốn mở rộng nó theo kích cỡ của UIImage.) Bạn có biết nếu điều này có thể xảy ra không?
DivideByZer0
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.