Come funzionano le immagini vettoriali in Xcode (ovvero file pdf)?


177

Come funziona il supporto vettoriale in Xcode 6?

Quando provo a ridimensionare un'immagine, sembra frastagliata, cosa dà?

Risposte:


351

Come usare i vettori in Xcode (7 e 6.3+):

  1. Salvare un'immagine come file .pdf nella dimensione @ 1x corretta (ad es. 24x24 per un pulsante della barra degli strumenti ).
  2. Nel tuo file Images.xcassets , crea un nuovo set di immagini .
  3. In Impostazioni attributi , imposta i fattori di scala su Singolo vettore .
  4. Trascina e rilascia il tuo file pdf nella sezione Tutto, universale .
  5. Ora puoi fare riferimento alla tua immagine con il suo nome, proprio come faresti con qualsiasi file .png .

    UIImage(named: "myImage")

Come utilizzare i vettori nelle versioni precedenti di Xcode (6.0 - 6.2):

  • Seguire i passaggi precedenti, ad eccezione del passaggio 3, impostare Tipi su Vettori .

Come funzionano i vettori in Xcode

Il supporto vettoriale è confuso in Xcode, perché quando la maggior parte delle persone pensa ai vettori, pensa alle immagini che possono ridimensionarsi su e giù e comunque avere un bell'aspetto. Tuttavia, Xcode 6 e 7 non hanno il supporto vettoriale completo per iOS, quindi le cose funzionano in modo leggermente diverso.

Il sistema vettoriale è davvero semplice . Prende la tua .pdfimmagine, e crea @1x.png, @2x.pnge @3x.pngle attività in fase di compilazione . (È possibile utilizzare uno strumento per esaminare il contenuto di Assets.car per verificarlo.)

Ad esempio, supponiamo che ti venga dato foo.pdfche è un asset vettoriale 44x44. Al momento della generazione genererà i seguenti file:

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

Questo funziona allo stesso modo per qualsiasi immagine di dimensioni. Ad esempio, se hai bar.pdf100x100, otterrai:

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

implicazioni:

  • Non è possibile scegliere una nuova dimensione per l'immagine ; avrà un bell'aspetto solo se lo mantieni nella dimensione 44x44. Il motivo è che il supporto vettoriale completo non è implementato . L'unica cosa che fanno questi vettori è farti risparmiare tempo per salvare le tue risorse di immagini. Se disponi di uno strumento (ad esempio uno script di Photoshop) che lo rende già un processo in una sola fase, l'unica cosa che otterrai utilizzando i vettori pdf è il supporto a prova di futuro (ad esempio se in iOS 9 Apple inizia a richiedere risorse @ 4x, questi funzioneranno) e avrai meno file da conservare .
  • Dovresti chiedere tutti i tuoi beni nella dimensione @ 1x, salvati come file PDF . Tra le altre cose, ciò consentirà a UIImageViews di avere la dimensione del contenuto intrinseco corretta.

Perché (probabilmente) funziona in questo modo:

  • Questo lo rende retrocompatibile con le versioni precedenti di iOS.
  • Il ridimensionamento dei vettori può essere un'attività intensiva computazionale in fase di esecuzione; implementandolo in questo modo, non ci sono hit di performance .

8
Bello scrivere. Questo è discusso nella Sessione 411 del WWDC 2014 - "Novità in Interface Builder" alle 44:13. Si noti che dicono che la rasterizzazione viene eseguita al momento della creazione. Inoltre, in modo interessante sul MAC utilizzerà i vettori in fase di esecuzione. Ad un certo punto in futuro, speriamo che anche iOS lo faccia.
Mike Vosseller,

15
Sfortunatamente non ridimensiona i valori della sezione. Quindi, se si tagliano gli angoli a 5, questo non verrà ridimensionato su 10 e 15 per le immagini 2x e 3x.
Jesse,

5
@Jesse se vuoi ridimensionare i valori della sezione, puoi farlo tu stesso nel codice usando resizableImageWithCapInsets:e dividendo i valori della sezione per[UIScreen mainScreen].scale
Arie Litovsky,

1
Per chiarire il suggerimento di @ArieLitovsky sull'affettamento: è necessario rimuovere l'affettamento dall'asset e spostarlo in codice, qualcosa del genereCGFloat scale = [UIScreen mainScreen].scale; UIImage *image = [[UIImage imageNamed:@"my_unsliced_asset"] resizableImageWithCapInsets:UIEdgeInsetsMake(10 * scale, 11 * scale, 12 * scale, 13 * scale)];
glyuck

6
Come posso fare per XCode 8? l'opzione sembra essere scomparsa!
Gerald

26

In Xcode 8, puoi ancora aggiungere un pdf, creare un nuovo set di immagini e, nella finestra di ispezione degli attributi, impostare l'opzione Scala su scala singola. inserisci qui la descrizione dell'immagine


15

Questo è un supplemento alla risposta eccellente di @Senseful.

Come realizzare immagini vettoriali in formato .pdf

Dirò come farlo in Inkscape poiché è gratuito e open source ma altri programmi dovrebbero essere simili.

In Inkscape:

  1. Crea un nuovo progetto.
  2. Vai a File> Proprietà del documento e imposta la dimensione della pagina personalizzata su qualunque sia la dimensione @ 1x (44x44, 100x100, ecc.) Con le unità in px.
  3. Crea la tua opera d'arte.
  4. Vai a File> Salva con nome ...> Formato documento stampabile (* .pdf)> Salva> OK. (In alternativa, puoi andare su Stampa> Stampa su file> Formato di output: PDF> Stampa ma non ci sono tante opzioni.)

Appunti:

  • Come indicato nella risposta accettata, non è possibile ridimensionare l'immagine poiché Xcode produce ancora le immagini rasterizzate al momento della creazione. Se è necessario ridimensionare l'immagine, è necessario creare un nuovo file .pdf con dimensioni diverse.
  • Se hai già un'immagine .svg della dimensione della pagina sbagliata, procedi come segue:

    1. Modifica le dimensioni della pagina (Inkscape> File> Proprietà documento)
    2. Seleziona tutti gli oggetti (Ctrl + A) nello spazio di lavoro e ridimensionali per adattarli alle nuove dimensioni della pagina. (Tenere premuto Ctrl per mantenere le dimensioni.)
  • Per convertire un file .svg in un .pdf puoi anche trovare utility online per fare il lavoro per te. Ecco un esempio da questa risposta . Questo ha il vantaggio di permetterti di impostare facilmente la dimensione .pdf.

Ulteriori letture


12

Per coloro che non hanno ancora effettuato l'aggiornamento, sono state apportate modifiche in Xcode 9 (iOS 11).

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

In poche parole, il Catalogo risorse ora include la nuova casella di controllo in Impostazioni attributi denominata "Conserva dati vettoriali". Se selezionato, i dati PDF verranno inclusi nel file binario compilato, aumentandone ovviamente le dimensioni. Ma offre a iOS la possibilità di ridimensionare i dati vettoriali in entrambe le direzioni e fornire belle immagini (con le sue difficoltà). Per iOS inferiore a 11, vengono utilizzati i vecchi meccanismi di ridimensionamento descritti nelle risposte verso l'alto.


1

Puoi usare normali file PDF all'interno del tuo progetto come immagini vettoriali e renderizzare immagini di qualsiasi dimensione usando questa estensione. In questo modo è meglio perché iOS non genererà immagini .PNG dai tuoi file PDF, inoltre puoi renderizzare le immagini con qualsiasi dimensione tu voglia:

    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
Ho provato questo, ma non sembra che ridimensiona l'immagine fino a dimensioni di pixel più grandi? Lo stesso UIImage che sto ottenendo ha le dimensioni corrette; è solo che l'immagine vettoriale è centrata e sempre alla dimensione originale dei pixel del PDF. (Volevo ridimensionarlo in base alle dimensioni di UIImage.) Sai se questo sarebbe possibile?
DivideByZer0,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.