Wie funktionieren Vektorgrafiken in Xcode (dh PDF-Dateien)?


176

Wie funktioniert die Vektorunterstützung in Xcode 6?

Wenn ich versuche, die Größe eines Bildes zu ändern, sieht es gezackt aus. Was gibt es?

Antworten:


351

Verwendung von Vektoren in Xcode (7 und 6.3+):

  1. Speichern Sie ein Bild als PDF- Datei in der richtigen Größe von @ 1x (z. B. 24x24 für eine Symbolleistenschaltfläche ).
  2. In Ihrer Images.xcassets Datei, erstellen Sie ein neues Bild festlegen .
  3. Setzen Sie im Attributinspektor die Skalierungsfaktoren auf Einzelvektor .
  4. Ziehen Sie Ihre PDF-Datei per Drag & Drop in den Bereich All, Universal .
  5. Sie können jetzt wie bei jeder PNG- Datei anhand des Namens auf Ihr Bild verweisen .

    UIImage(named: "myImage")

Verwendung von Vektoren in älteren Versionen von Xcode (6.0 - 6.2):

  • Befolgen Sie die obigen Schritte, mit Ausnahme von Schritt 3, und setzen Sie Typen auf Vektoren .

Wie Vektoren in Xcode funktionieren

Die Vektorunterstützung ist in Xcode verwirrend, denn wenn die meisten Menschen an Vektoren denken, denken sie an Bilder, die sich vergrößern und verkleinern lassen und trotzdem gut aussehen. Xcode 6 und 7 bieten jedoch keine vollständige Vektorunterstützung für iOS, sodass die Dinge etwas anders funktionieren.

Das Vektorsystem ist wirklich einfach . Es braucht Ihr .pdfBild, und schafft @1x.png, @2x.pngund @3x.pngVermögenswerte zum Erstellungszeitpunkt . (Sie können ein Tool verwenden, um den Inhalt von Assets.car zu überprüfen und dies zu überprüfen.)

foo.pdfAngenommen , Sie erhalten ein 44x44-Vektor-Asset. Beim Erstellen werden die folgenden Dateien generiert:

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

Dies funktioniert für Bilder jeder Größe gleich. Wenn Sie beispielsweise bar.pdfeine Größe von 100 x 100 haben, erhalten Sie:

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

Implikationen:

  • Sie können keine neue Größe für das Bild auswählen . es wird nur gut aussehen, wenn Sie es auf der Größe 44x44 halten. Der Grund ist, dass keine vollständige Vektorunterstützung implementiert ist . Diese Vektoren sparen Ihnen nur Zeit beim Speichern Ihrer Bildelemente. Wenn Sie über ein Tool (z. B. ein Photoshop-Skript) verfügen, das dies bereits zu einem einstufigen Vorgang macht, erhalten Sie durch die Verwendung von PDF-Vektoren nur eine zukunftssichere Unterstützung (z. B. wenn Apple in iOS 9 anfängt, @ 4x-Assets zu benötigen). diese funktionieren einfach) und Sie müssen weniger Dateien verwalten .
  • Sie sollten alle Ihre Assets in der Größe @ 1x anfordern, die als PDF-Dateien gespeichert sind . Auf diese Weise kann UIImageViews unter anderem die richtige Größe des Inhalts haben.

Warum es (wahrscheinlich) so funktioniert:

  • Dies macht es abwärtskompatibel mit früheren iOS-Versionen.
  • Das Ändern der Größe von Vektoren kann zur Laufzeit eine rechenintensive Aufgabe sein. Wenn Sie es auf diese Weise implementieren, gibt es keine Leistungseinbußen .

8
Schön zu schreiben. Dies wird in der WWDC-Sitzung 411 2014 - "Was ist neu in Interface Builder?" Um 44:13 Uhr besprochen. Beachten Sie, dass die Rasterung zum Zeitpunkt der Erstellung durchgeführt wird. Interessanterweise werden auf dem MAC zur Laufzeit Vektoren verwendet. Irgendwann in der Zukunft hoffentlich auch iOS.
Mike Vosseller

15
Die Slice-Werte werden leider nicht skaliert. Wenn Sie also Ecken bei 5 schneiden, wird sie für die 2x- und 3x-Bilder nicht auf 10 und 15 skaliert.
Jesse

5
@ Jesse Wenn Sie die Slice-Werte skalieren möchten, können Sie dies selbst im Code tun, resizableImageWithCapInsets:indem Sie Ihre Slice-Werte verwenden und durch[UIScreen mainScreen].scale
Arie Litovsky

1
Um den @ ArieLitovsky-Vorschlag zum Schneiden zu verdeutlichen: Sie sollten das Schneiden aus dem Asset entfernen und in den Code verschieben, etwaCGFloat scale = [UIScreen mainScreen].scale; UIImage *image = [[UIImage imageNamed:@"my_unsliced_asset"] resizableImageWithCapInsets:UIEdgeInsetsMake(10 * scale, 11 * scale, 12 * scale, 13 * scale)];
Glyuck,

6
Wie mache ich das für XCode 8? Die Option scheint verschwunden zu sein!
Gerald

26

In Xcode 8 können Sie weiterhin ein PDF hinzufügen, einen neuen Bildsatz erstellen und im Attributinspektor die Option Skalen auf Einzelskala festlegen. Geben Sie hier die Bildbeschreibung ein


15

Dies ist eine Ergänzung zu der hervorragenden Antwort von @Senseful.

So erstellen Sie Vektorbilder im PDF-Format

Ich werde erklären, wie dies in Inkscape gemacht wird, da es kostenlos und Open Source ist, aber andere Programme sollten ähnlich sein.

In Inkscape:

  1. Erstellen Sie ein neues Projekt.
  2. Gehen Sie zu Datei> Dokumenteigenschaften und stellen Sie die benutzerdefinierte Seitengröße auf die @ 1x-Größe (44x44, 100x100 usw.) mit den Einheiten in px ein.
  3. Machen Sie Ihr Kunstwerk.
  4. Gehen Sie zu Datei> Speichern unter ...> Druckbares Dokumentformat (* .pdf)> Speichern> OK. (Alternativ können Sie zu Drucken> In Datei drucken> Ausgabeformat: PDF> Drucken gehen, es gibt jedoch nicht so viele Optionen.)

Anmerkungen:

  • Wie in der akzeptierten Antwort erwähnt, können Sie die Größe Ihres Bildes nicht ändern, da Xcode die gerasterten Bilder zum Zeitpunkt der Erstellung noch erstellt. Wenn Sie die Größe Ihres Bildes ändern müssen, sollten Sie eine neue PDF-Datei mit einer anderen Größe erstellen.
  • Wenn Sie bereits ein .svg-Bild mit der falschen Seitengröße haben, gehen Sie wie folgt vor:

    1. Ändern Sie die Seitengröße (Inkscape> Datei> Dokumenteigenschaften)
    2. Wählen Sie alle Objekte (Strg + A) im Arbeitsbereich aus und passen Sie die Größe an die neue Seitengröße an. (Halten Sie die Strg-Taste gedrückt, um die Seitengröße beizubehalten.)
  • Um eine .svg-Datei in eine .pdf-Datei zu konvertieren, finden Sie auch Online-Dienstprogramme, die die Arbeit für Sie erledigen. Hier ist ein Beispiel aus dieser Antwort . Dies hat den Vorteil, dass Sie die PDF-Größe einfach einstellen können.

Weiterführende Literatur


12

Für diejenigen, die noch nicht aktualisiert wurden, gab es Änderungen in Xcode 9 (iOS 11).

Was ist neu in Cocoa Touch (WWDC 2017 Session 201) (@ 32: 55) https://developer.apple.com/videos/play/wwdc2017/201/

Mit wenigen Worten, der Asset-Katalog enthält jetzt das neue Kontrollkästchen im Attributinspektor mit dem Namen "Vektordaten beibehalten". Wenn diese Option aktiviert ist, werden PDF-Daten in die kompilierte Binärdatei aufgenommen, wodurch sich die Größe natürlich erhöht. Für iOS besteht jedoch die Möglichkeit, die Vektordaten in beide Richtungen zu skalieren und schöne Bilder bereitzustellen (mit eigenen Schwierigkeiten). Für iOS unter 11 werden alte Skalierungsmechanismen verwendet, die in den Antworten nach oben beschrieben sind.


1

Mit dieser Erweiterung können Sie normale PDF-Dateien in Ihrem Projekt als Vektorbilder verwenden und Bilder jeder Größe rendern. Dieser Weg ist viel besser, da iOS keine PNG-Bilder aus Ihren PDF-Dateien generiert. Außerdem können Sie Bilder mit jeder gewünschten Größe rendern:

    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
Ich habe es versucht, aber es scheint nicht so, als würde es das Bild auf größere Pixel skalieren? Das UIImage selbst, das ich bekomme, hat die richtige Größe; Es ist nur so, dass das Vektorbild zentriert ist und immer noch die ursprüngliche Pixelgröße der PDF-Datei hat. (Ich wollte es auf die Größe des UIImage skalieren.) Wissen Sie, ob dies möglich wäre?
DivideByZer0
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.