Bagaimana cara kerja gambar vektor di Xcode (mis. File pdf)?

176

Bagaimana cara kerja dukungan vektor di Xcode 6?

Ketika saya mencoba mengubah ukuran gambar, terlihat bergerigi, apa yang terjadi?

Masuk akal
sumber

Jawaban:

351

Cara menggunakan vektor di Xcode (7 dan 6.3+):

  1. Simpan gambar sebagai file .pdf pada ukuran @ 1x yang tepat (mis. 24x24 untuk tombol bilah alat ).
  2. Di file Images.xcassets Anda , buat Set Gambar baru .
  3. Di Inspektur Atribut , atur Scale Factors ke Single Vector .
  4. Seret dan jatuhkan file pdf Anda ke bagian Semua, Universal .
  5. Anda sekarang dapat merujuk ke gambar Anda dengan namanya, seperti yang Anda lakukan pada file .png .

    UIImage(named: "myImage")

Cara menggunakan vektor di versi Xcode yang lebih lama (6.0 - 6.2):

  • Ikuti langkah-langkah di atas, kecuali untuk langkah 3, atur Jenis ke Vektor .

Bagaimana vektor bekerja di Xcode

Dukungan vektor membingungkan dalam Xcode, karena ketika kebanyakan orang memikirkan vektor, mereka memikirkan gambar yang dapat naik turun dan masih terlihat bagus. Namun, Xcode 6 dan 7 tidak memiliki dukungan vektor penuh untuk iOS, jadi semuanya berjalan sedikit berbeda.

Sistem vektor sangat sederhana . Dibutuhkan Anda .pdfgambar, dan menciptakan @1x.png, @2x.pngdan @3x.pngaset pada waktu membangun . (Anda dapat menggunakan alat untuk memeriksa konten Assets.car untuk memverifikasi ini.)

Misalnya, anggap Anda diberi foo.pdfaset vektor 44x44. Pada saat membangun akan menghasilkan file-file berikut:

Ini berfungsi sama untuk ukuran gambar apa pun. Misalnya, jika Anda memiliki bar.pdfyang 100x100, Anda akan mendapatkan:


Implikasi:

  • Anda tidak dapat memilih ukuran baru untuk gambar ; itu hanya akan terlihat bagus jika Anda tetap pada ukuran 44x44. Alasannya adalah bahwa dukungan vektor penuh tidak diterapkan . Satu-satunya hal yang dilakukan vektor ini adalah menghemat waktu Anda menyimpan aset gambar Anda. Jika Anda memiliki alat (misalnya skrip Photoshop) yang sudah menjadikan ini proses satu langkah, satu-satunya hal yang akan Anda peroleh dengan menggunakan vektor pdf adalah dukungan tahan-masa depan (mis. Jika di iOS 9 Apple mulai membutuhkan aset @ 4x, ini hanya akan berfungsi), dan Anda akan memiliki lebih sedikit file untuk dipelihara .
  • Anda harus meminta semua aset Anda pada ukuran @ 1x, disimpan sebagai file PDF . Antara lain, ini akan memungkinkan UIImageViews untuk memiliki ukuran konten intrinsik yang benar.

Mengapa (mungkin) bekerja seperti ini:

  • Ini membuatnya kompatibel dengan versi iOS sebelumnya.
  • Mengubah ukuran vektor dapat menjadi tugas intensif komputasi saat runtime; dengan menerapkannya dengan cara ini, tidak ada hit kinerja .
Masuk akal
sumber
8
Menulis bagus. Ini dibahas pada 2014 WWDC Sesi 411 - "Apa yang Baru di Interface Builder" pada waktu 44:13. Perhatikan bahwa mereka mengatakan rasterisasi dilakukan pada waktu pembangunan. Menariknya juga pada MAC itu akan menggunakan vektor saat runtime. Pada titik yang jauh di masa depan semoga iOS juga.
Mike Vosseller
15
Sayangnya itu tidak menskalakan nilai slice. Jadi jika Anda mengiris sudut pada 5 itu tidak akan skala ke 10 dan 15 untuk gambar 2x dan 3x.
Jesse
5
@Jesse jika Anda ingin skala nilai slice, Anda dapat melakukannya sendiri dalam kode dengan menggunakan resizableImageWithCapInsets:dan membagi nilai slice Anda dengan[UIScreen mainScreen].scale
Arie Litovsky
1
Untuk mengklarifikasi saran @ArieLitovsky tentang mengiris: Anda harus menghapus mengiris dari aset dan memindahkannya ke kode, sesuatu sepertiCGFloat scale = [UIScreen mainScreen].scale; UIImage *image = [[UIImage imageNamed:@"my_unsliced_asset"] resizableImageWithCapInsets:UIEdgeInsetsMake(10 * scale, 11 * scale, 12 * scale, 13 * scale)];
glyuck
6
Bagaimana saya melakukan ini untuk XCode 8? opsi tampaknya telah menghilang!
Gerald
26

Di Xcode 8, Anda masih bisa menambahkan pdf, membuat Set Gambar baru, dan di Inspektur Atribut, atur opsi Timbangan ke Skala Tunggal. masukkan deskripsi gambar di sini

Maria
sumber
15

Ini adalah suplemen untuk jawaban yang sangat bagus oleh @Senseful.

Cara membuat gambar vektor dalam format .pdf

Saya akan memberi tahu cara melakukan ini di Inkscape karena gratis dan open source tetapi program lain harus serupa.

Dalam Inkscape:

  1. Buat proyek baru.
  2. Buka File> Document Properties dan atur ukuran halaman khusus ke apa pun ukuran @ 1x Anda (44x44, 100x100, dll.) Dengan unit dalam px.
  3. Buat karya seni Anda.
  4. Buka File> Simpan Sebagai ...> Format Dokumen yang Dapat Dicetak (* .pdf)> Simpan> OK. (Atau, Anda bisa pergi ke Cetak> Cetak ke File> Format keluaran: PDF> Cetak tetapi tidak ada banyak pilihan.)

Catatan:

  • Seperti yang disebutkan dalam jawaban yang diterima, Anda tidak dapat mengubah ukuran gambar Anda karena Xcode masih menghasilkan gambar raster pada saat membangun. Jika Anda perlu mengubah ukuran gambar, Anda harus membuat file .pdf baru dengan ukuran berbeda.
  • Jika Anda sudah memiliki gambar .svg yang ukuran halamannya salah, lakukan hal berikut:

    1. Ubah ukuran halaman (Inkscape> File> Properti Dokumen)
    2. Pilih semua objek (Ctrl + A) pada ruang kerja dan ubah ukurannya agar sesuai dengan ukuran halaman baru. (Tahan Ctrl untuk menjaga ukuran aspek.)
  • Untuk mengonversi file .svg menjadi .pdf Anda juga dapat menemukan utilitas online untuk melakukan pekerjaan itu untuk Anda. Inilah satu contoh dari jawaban ini . Ini memiliki manfaat memungkinkan Anda untuk mengatur ukuran .pdf dengan mudah.

Bacaan lebih lanjut

Suragch
sumber
12

Bagi mereka yang masih belum memperbarui, ada perubahan di Xcode 9 (iOS 11).

Apa yang baru di Cocoa Touch (WWDC 2017 Session 201) (@ 32: 55) https://developer.apple.com/videos/play/wwdc2017/201/

Dalam beberapa kata, Katalog Aset sekarang menyertakan kotak centang baru di Inspektur Atribut bernama "Preserve Vector Data". Ketika diperiksa, data PDF akan dimasukkan dalam biner yang dikompilasi, tentu saja memperbesar ukurannya. Tapi itu memberi kesempatan bagi iOS untuk skala data vektor di kedua arah dan memberikan gambar yang bagus. (Dengan kesulitan sendiri). Untuk iOS di bawah 11, mekanisme penskalaan lama yang dijelaskan dalam jawaban di atas digunakan.

Dren
sumber
1

Anda dapat menggunakan file PDF normal di dalam proyek Anda sebagai gambar Vektor dan membuat gambar dari berbagai ukuran menggunakan ekstensi ini. Cara ini jauh lebih baik karena iOS tidak akan menghasilkan gambar .PNG dari file PDF Anda, plus Anda dapat membuat gambar dengan ukuran apa pun yang Anda inginkan:

    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
        }
    }

}
Bruno Paulino
sumber
1
Saya sudah mencoba ini, tetapi sepertinya tidak memperbesar gambar hingga ukuran piksel yang lebih besar? UIImage itu sendiri yang saya dapatkan adalah ukuran yang benar; hanya saja gambar vektor terpusat dan masih pada ukuran piksel asli dari PDF. (Saya ingin skala ke ukuran UIImage.) Apakah Anda tahu jika ini mungkin?
DivideByZer0