Wie kann ich die Größe des UIImage ändern, um die Größe des Upload-Bildes zu verringern?


76

Ich habe bei Google gesucht und bin nur auf Bibliotheken gestoßen, die entweder die Höhe / Breite reduzieren oder das Erscheinungsbild von UIImage über CoreImage bearbeiten. Aber ich habe keine Bibliothek gesehen oder gefunden, in der erklärt wird, wie die Bildgröße reduziert werden kann. Wenn sie hochgeladen wird, ist sie nicht die volle Bildgröße.

Bisher habe ich Folgendes:

        if image != nil {
        //let data = NSData(data: UIImagePNGRepresentation(image))
        let data = UIImagePNGRepresentation(image)
        body.appendString("--\(boundary)\r\n")
        body.appendString("Content-Disposition: form-data; name=\"image\"; filename=\"randomName\"\r\n")
        body.appendString("Content-Type: image/png\r\n\r\n")
        body.appendData(data)
        body.appendString("\r\n")
    }

und es sendet 12 MB Fotos. Wie kann ich das auf 1 MB reduzieren? Vielen Dank!

Antworten:


188

Xcode 9 • Swift 4 oder höher

Bearbeiten / Aktualisieren: Für iOS10 + können wir UIGraphicsImageRenderer verwenden . Überprüfen Sie für ältere Swift-Syntax den Bearbeitungsverlauf.

extension UIImage {
    func resized(withPercentage percentage: CGFloat, isOpaque: Bool = true) -> UIImage? {
        let canvas = CGSize(width: size.width * percentage, height: size.height * percentage)
        let format = imageRendererFormat
        format.opaque = isOpaque
        return UIGraphicsImageRenderer(size: canvas, format: format).image {
            _ in draw(in: CGRect(origin: .zero, size: canvas))
        }
    }
    func resized(toWidth width: CGFloat, isOpaque: Bool = true) -> UIImage? {
        let canvas = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))
        let format = imageRendererFormat
        format.opaque = isOpaque
        return UIGraphicsImageRenderer(size: canvas, format: format).image {
            _ in draw(in: CGRect(origin: .zero, size: canvas))
        }
    }
}

Verwendung:

let image = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))!

let thumb1 = image.resized(withPercentage: 0.1)
let thumb2 = image.resized(toWidth: 72.0)

2
Tolles Zeug, Leo. Vielen Dank.
MolonLabe

2
Sie sollten die Swift 2-Syntax unten hinzufügen. Jemand hat Ihren Code kopiert / eingefügt und 9 Upvotes erhalten. Unverdient, wenn Sie mich fragen ...
David Seek

6
LeoDabus, ich denke, dies ist die nicht richtige Antwort, aber eine sehr gute Lösung für andere Probleme. Die Frage hier ist, wie wir 12 MB auf 1 MB reduzieren können, nicht basierend auf dem Prozentsatz oder der Bildgröße (Breite oder Höhe), sondern basierend auf der Dateigröße. @EBDOKUM kann möglicherweise zu diesem Ergebnis führen, da die Reduzierung der Bildgröße (Breite und Höhe) keine Reduzierung der Dateigröße garantiert. Nur die Größe wird verkleinert, aber die Dateigröße kann je nach verwendetem Bild zunehmen oder abnehmen.
Nycdanie

2
@ ChrisW. Ich spreche nicht von Photoshop oder einer Web-Engine. Sie können gerne Ihre Antwort auf die Frage posten, wie ein PNG in iOS (Swift) komprimiert wird.
Leo Dabus

3
Sie sollten hinzufügen, guard size.width > width else { return self }damit kleinere Bilder nicht größer werden.
Band

70

Dies ist der Weg, den ich befolgt habe, um die Bildgröße zu ändern.

 -(UIImage *)resizeImage:(UIImage *)image
{
   float actualHeight = image.size.height;
   float actualWidth = image.size.width;
   float maxHeight = 300.0;
   float maxWidth = 400.0;
   float imgRatio = actualWidth/actualHeight;
   float maxRatio = maxWidth/maxHeight;
   float compressionQuality = 0.5;//50 percent compression

   if (actualHeight > maxHeight || actualWidth > maxWidth)
   {
    if(imgRatio < maxRatio)
    {
        //adjust width according to maxHeight
        imgRatio = maxHeight / actualHeight;
        actualWidth = imgRatio * actualWidth;
        actualHeight = maxHeight;
    }
    else if(imgRatio > maxRatio)
    {
        //adjust height according to maxWidth
        imgRatio = maxWidth / actualWidth;
        actualHeight = imgRatio * actualHeight;
        actualWidth = maxWidth;
    }
    else
    {
        actualHeight = maxHeight;
        actualWidth = maxWidth;
    }
   }

   CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
   UIGraphicsBeginImageContext(rect.size);
   [image drawInRect:rect];
   UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
   NSData *imageData = UIImageJPEGRepresentation(img, compressionQuality);
   UIGraphicsEndImageContext();

   return [UIImage imageWithData:imageData];

}

Mit dieser Methode wurde mein Bild mit 6,5 MB auf 104 KB reduziert.

Swift 4 Code:

func resize(_ image: UIImage) -> UIImage {
    var actualHeight = Float(image.size.height)
    var actualWidth = Float(image.size.width)
    let maxHeight: Float = 300.0
    let maxWidth: Float = 400.0
    var imgRatio: Float = actualWidth / actualHeight
    let maxRatio: Float = maxWidth / maxHeight
    let compressionQuality: Float = 0.5
    //50 percent compression
    if actualHeight > maxHeight || actualWidth > maxWidth {
        if imgRatio < maxRatio {
            //adjust width according to maxHeight
            imgRatio = maxHeight / actualHeight
            actualWidth = imgRatio * actualWidth
            actualHeight = maxHeight
        }
        else if imgRatio > maxRatio {
            //adjust height according to maxWidth
            imgRatio = maxWidth / actualWidth
            actualHeight = imgRatio * actualHeight
            actualWidth = maxWidth
        }
        else {
            actualHeight = maxHeight
            actualWidth = maxWidth
        }
    }
    let rect = CGRect(x: 0.0, y: 0.0, width: CGFloat(actualWidth), height: CGFloat(actualHeight))
    UIGraphicsBeginImageContext(rect.size)
    image.draw(in: rect)
    let img = UIGraphicsGetImageFromCurrentImageContext()
    let imageData = img?.jpegData(compressionQuality: CGFloat(compressionQuality)) 
    UIGraphicsEndImageContext()
    return UIImage(data: imageData!) ?? UIImage()
}

Was ist mit der Auflösung? Ich möchte die Breite auf maximal 1024 einstellen, aber die Höhe hängt vom Bild ab, damit ich das Seitenverhältnis beibehalten kann.
Jay

Hier komprimiere ich auch das Bild. Wenn Sie die gleiche Auflösung wünschen, kommentieren Sie diese Zeile NSData * imageData = UIImageJPEGRepresentation (img, compressQuality); und wir müssen maxHeight und maxWidth so auswählen, dass das Seitenverhältnis gleich sein sollte.
user4261201

1
Wie man minimale Breite und Höhe gibt. Damit das Bild nicht unter eine bestimmte Größe komprimiert wird
user2185354

SWIFT 4.2 ändere diese Zeile: let imageData = UIImageJPEGRepresentation (img!, CGFloat (Komprimierungsqualität)) Dazu: let imageData = img? .JpegData (Komprimierungsqualität: CGFloat (Komprimierungsqualität))
ttorbik

30

Für den Fall, dass jemand mit Swift 3 und 4 die Größe des Bilds auf weniger als 1 MB ändern möchte .

Kopieren Sie einfach diese Erweiterung und fügen Sie sie ein :

extension UIImage {

func resized(withPercentage percentage: CGFloat) -> UIImage? {
    let canvasSize = CGSize(width: size.width * percentage, height: size.height * percentage)
    UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale)
    defer { UIGraphicsEndImageContext() }
    draw(in: CGRect(origin: .zero, size: canvasSize))
    return UIGraphicsGetImageFromCurrentImageContext()
}

func resizedTo1MB() -> UIImage? {
    guard let imageData = UIImagePNGRepresentation(self) else { return nil }

    var resizingImage = self
    var imageSizeKB = Double(imageData.count) / 1000.0 // ! Or devide for 1024 if you need KB but not kB

    while imageSizeKB > 1000 { // ! Or use 1024 if you need KB but not kB
        guard let resizedImage = resizingImage.resized(withPercentage: 0.9),
            let imageData = UIImagePNGRepresentation(resizedImage)
            else { return nil }

        resizingImage = resizedImage
        imageSizeKB = Double(imageData.count) / 1000.0 // ! Or devide for 1024 if you need KB but not kB
    }

    return resizingImage
}
}

Und benutze:

let resizedImage = originalImage.resizedTo1MB()

Bearbeiten: Bitte beachten Sie, dass die Benutzeroberfläche blockiert wird. Wechseln Sie daher zum Hintergrund-Thread, wenn Sie der Meinung sind, dass dies der richtige Weg für Ihren Fall ist.


In den whileSchleifen sollte guardder UIImagePNGRepresentationAufruf resizedImagenicht verwenden resizingImage. Verursacht eine zusätzliche Schleife ...
Mike M

12

Wie Leo Answer, jedoch nur wenige Änderungen für SWIFT 2.0

 extension UIImage {
    func resizeWithPercentage(percentage: CGFloat) -> UIImage? {
        let imageView = UIImageView(frame: CGRect(origin: .zero, size: CGSize(width: size.width * percentage, height: size.height * percentage)))
        imageView.contentMode = .ScaleAspectFit
        imageView.image = self
        UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, scale)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        imageView.layer.renderInContext(context)
        guard let result = UIGraphicsGetImageFromCurrentImageContext() else { return nil }
        UIGraphicsEndImageContext()
        return result
    }

    func resizeWithWidth(width: CGFloat) -> UIImage? {
        let imageView = UIImageView(frame: CGRect(origin: .zero, size: CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))))
        imageView.contentMode = .ScaleAspectFit
        imageView.image = self
        UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, scale)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        imageView.layer.renderInContext(context)
        guard let result = UIGraphicsGetImageFromCurrentImageContext() else { return nil }
        UIGraphicsEndImageContext()
        return result
    }
}

2
Kommentar über den Unterschied wäre schön
David Seek

Die Logik war dieselbe, aber die Leo-Antwort war für Swift 3.0 und ich habe sie einfach in Swift 2.0 geschrieben.
Jagdeep

5

Hier ist die Antwort von user4261201, aber in Kürze, die ich derzeit verwende:

func compressImage (_ image: UIImage) -> UIImage {

    let actualHeight:CGFloat = image.size.height
    let actualWidth:CGFloat = image.size.width
    let imgRatio:CGFloat = actualWidth/actualHeight
    let maxWidth:CGFloat = 1024.0
    let resizedHeight:CGFloat = maxWidth/imgRatio
    let compressionQuality:CGFloat = 0.5

    let rect:CGRect = CGRect(x: 0, y: 0, width: maxWidth, height: resizedHeight)
    UIGraphicsBeginImageContext(rect.size)
    image.draw(in: rect)
    let img: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    let imageData:Data = UIImageJPEGRepresentation(img, compressionQuality)!
    UIGraphicsEndImageContext()

    return UIImage(data: imageData)!

}

1
Das Konvertieren eines UIImage in Daten und zurück in UIImage ist sinnlos. Übrigens verschlechtern Sie die Bildqualität, indem Sie sie komprimieren.
Leo Dabus

1
@LeoDabus danke für diesen Einblick, ich werde Ihre Antwort als die richtige auswählen!
Jay


2

Wenn Sie ein Bild im NSDataFormat hochladen , verwenden Sie Folgendes :

NSData *imageData = UIImageJPEGRepresentation(yourImage, floatValue);

yourImageist dein UIImage. floatvalueist der Komprimierungswert (0,0 bis 1,0)

Das obige ist, um Bild zu konvertieren JPEG.

Zur PNGVerwendung:UIImagePNGRepresentation

Hinweis: Der obige Code befindet sich in Objective-C. Bitte überprüfen Sie, wie Sie NSData in Swift definieren.


Wenn ich mir Sorgen um die Auflösung mache, wie würde ich eine maximale Breite festlegen, aber die Höhe durch das Bild selbst bestimmen lassen?
Jay

2
UIImagePNGRepresentation hat keine Komprimierungsoption.
Alec.

1

Mit dieser Option können Sie die gewünschte Größe steuern:

func jpegImage(image: UIImage, maxSize: Int, minSize: Int, times: Int) -> Data? {
    var maxQuality: CGFloat = 1.0
    var minQuality: CGFloat = 0.0
    var bestData: Data?
    for _ in 1...times {
        let thisQuality = (maxQuality + minQuality) / 2
        guard let data = image.jpegData(compressionQuality: thisQuality) else { return nil }
        let thisSize = data.count
        if thisSize > maxSize {
            maxQuality = thisQuality
        } else {
            minQuality = thisQuality
            bestData = data
            if thisSize > minSize {
                return bestData
            }
        }
    }
    return bestData
}

Beispiel für einen Methodenaufruf:

jpegImage(image: image, maxSize: 500000, minSize: 400000, times: 10)  

Es wird versucht, eine Datei zwischen einer maximalen und einer minimalen Größe von maxSize und minSize abzurufen, aber nur mal versuchen. Wenn es innerhalb dieser Zeit fehlschlägt, wird null zurückgegeben.


1

Ich denke, der einfachste Weg, Swift selbst zu komprimieren, um das Bild in komprimierte Daten zu komprimieren, ist der Code in Swift 4.2

let imageData = yourImageTobeCompressed.jpegData(compressionQuality: 0.5)

und Sie können diese imageData senden, um sie auf den Server hochzuladen.


1

Ich denke, der Kern der Frage hier ist, wie die Daten eines UIImage vor dem Hochladen auf einen Server zuverlässig auf eine bestimmte Größe verkleinert werden können, anstatt nur das UIImage selbst zu verkleinern.

Die Verwendung func jpegData(compressionQuality: CGFloat) -> Data?funktioniert gut, wenn Sie nicht auf eine bestimmte Größe komprimieren müssen. In bestimmten Fällen finde ich es jedoch nützlich, unter einer bestimmten angegebenen Dateigröße komprimieren zu können. In diesem Fall jpegDataist dies unzuverlässig, und das iterative Komprimieren eines Bildes auf diese Weise führt zu einem Plateau der Dateigröße (und kann sehr teuer sein). Stattdessen ziehe ich es vor, die Größe des UIImage selbst wie in Leos Antwort zu reduzieren , dann in jpegData zu konvertieren und iterativ zu überprüfen, ob die reduzierte Größe unter dem von mir gewählten Wert liegt (innerhalb eines von mir festgelegten Bereichs). Ich passe den Multiplikator für den Komprimierungsschritt basierend auf dem Verhältnis der aktuellen Dateigröße zur gewünschten Dateigröße an, um die ersten Iterationen zu beschleunigen, die am teuersten sind (da die Dateigröße zu diesem Zeitpunkt die größte ist).

Swift 5

extension UIImage {
    func resized(withPercentage percentage: CGFloat, isOpaque: Bool = true) -> UIImage? {
        let canvas = CGSize(width: size.width * percentage, height: size.height * percentage)
        let format = imageRendererFormat
        format.opaque = isOpaque
        return UIGraphicsImageRenderer(size: canvas, format: format).image {
            _ in draw(in: CGRect(origin: .zero, size: canvas))
        }
    }
    
    func compress(to kb: Int, allowedMargin: CGFloat = 0.2) -> Data {
        guard kb > 10 else { return Data() } // Prevents user from compressing below a limit (10kb in this case).
        let bytes = kb * 1024
        var compression: CGFloat = 1.0
        let step: CGFloat = 0.05
        var holderImage = self
        var complete = false
        while(!complete) {
            guard let data = holderImage.jpegData(compressionQuality: 1.0) else { break }
            let ratio = data.count / bytes
            if data.count < Int(CGFloat(bytes) * (1 + allowedMargin)) {
                complete = true
                return data
            } else {
                let multiplier:CGFloat = CGFloat((ratio / 5) + 1)
                compression -= (step * multiplier)
            }
            guard let newImage = holderImage.resized(withPercentage: compression) else { break }
            holderImage = newImage
        }
        
        return Data()
    }
}
 

Und Verwendung:

let data = image.compress(to: 1000)

Sie geben jedoch leere Daten zurück. Ich nehme an du meinst return data?
Bawenang Rukmoko Pardian Putra

@BawenangRukmokoPardianPutra Das wird in dieser Funktion nicht aufgerufen, sondern erfüllt nur den Rückgabetyp der Funktion. Die Daten werden in der if-Anweisung der while-Schleife zurückgegeben. Ich sollte wahrscheinlich die Antwort auf das Werfen oder Verwenden von Optionen umgestalten, habe mich aber für eine einfache Verwendung entschieden. Ich sollte auch eine Guard-Anweisung hinzufügen, um das Komprimieren auf unrealistisch kleine Werte nicht zuzulassen.
Iron John Bonney

Guard-Anweisung hinzugefügt, um compress to 0Groß- und Kleinschreibung zu verhindern und die Komprimierung auf einen angemessenen Wert zu beschränken (in diesem Beispiel 10 KB).
Iron John Bonney

Ah ja, mein schlechtes. Ich sehe es jetzt.
Bawenang Rukmoko Pardian Putra

0

Dies habe ich in Swift 3 getan, um die Größe eines UIImage zu ändern. Es reduziert die Bildgröße auf weniger als 100 KB. Es funktioniert proportional!

extension UIImage {
    class func scaleImageWithDivisor(img: UIImage, divisor: CGFloat) -> UIImage {
        let size = CGSize(width: img.size.width/divisor, height: img.size.height/divisor)
        UIGraphicsBeginImageContext(size)
        img.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return scaledImage!
    }
}

Verwendung:

let scaledImage = UIImage.scaleImageWithDivisor(img: capturedImage!, divisor: 3)

0

Basierend auf der Antwort von Tung Fam. So ändern Sie die Größe auf eine bestimmte Dateigröße. Wie 0,7 MB können Sie diesen Code verwenden.

extension UIImage {

func resize(withPercentage percentage: CGFloat) -> UIImage? {
    var newRect = CGRect(origin: .zero, size: CGSize(width: size.width*percentage, height: size.height*percentage))
    UIGraphicsBeginImageContextWithOptions(newRect.size, true, 1)
    self.draw(in: newRect)
    defer {UIGraphicsEndImageContext()}
    return UIGraphicsGetImageFromCurrentImageContext()
}

func resizeTo(MB: Double) -> UIImage? {
    guard let fileSize = self.pngData()?.count else {return nil}
    let fileSizeInMB = CGFloat(fileSize)/(1024.0*1024.0)//form bytes to MB
    let percentage = 1/fileSizeInMB
    return resize(withPercentage: percentage)
}
}

0

Gleiches in Ziel-C:

Schnittstelle:

@interface UIImage (Resize)

- (UIImage *)resizedWithPercentage:(CGFloat)percentage;
- (UIImage *)resizeTo:(CGFloat)weight isPng:(BOOL)isPng jpegCompressionQuality:(CGFloat)compressionQuality;

@end

Implementierung :

#import "UIImage+Resize.h"

@implementation UIImage (Resize)

- (UIImage *)resizedWithPercentage:(CGFloat)percentage {
    CGSize canvasSize = CGSizeMake(self.size.width * percentage, self.size.height * percentage);
    UIGraphicsBeginImageContextWithOptions(canvasSize, false, self.scale);
    [self drawInRect:CGRectMake(0, 0, canvasSize.width, canvasSize.height)];
    UIImage *sizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return sizedImage;
}

- (UIImage *)resizeTo:(CGFloat)weight isPng:(BOOL)isPng jpegCompressionQuality:(CGFloat)compressionQuality {
    NSData *imageData = isPng ? UIImagePNGRepresentation(self) : UIImageJPEGRepresentation(self, compressionQuality);
    if (imageData && [imageData length] > 0) {
        UIImage *resizingImage = self;
        double imageSizeKB = [imageData length] / weight;

        while (imageSizeKB > weight) {
            UIImage *resizedImage = [resizingImage resizedWithPercentage:0.9];
            imageData = isPng ? UIImagePNGRepresentation(resizedImage) : UIImageJPEGRepresentation(resizedImage, compressionQuality);
            resizingImage = resizedImage;
            imageSizeKB = (double)(imageData.length / weight);
        }

        return resizingImage;
    }
    return nil;
}

Verwendung :

#import "UIImage+Resize.h"

UIImage *resizedImage = [self.picture resizeTo:2048 isPng:NO jpegCompressionQuality:1.0];

0

Wenn ich versuche, die akzeptierte Antwort zu verwenden, um die Größe eines Bilds für die Verwendung in meinem Projekt zu ändern, wird es sehr pixelig und verschwommen. Am Ende hatte ich diesen Code, um die Größe von Bildern zu ändern, ohne Pixelung oder Unschärfe hinzuzufügen:

func scale(withPercentage percentage: CGFloat)-> UIImage? {
        let cgSize = CGSize(width: size.width * percentage, height: size.height * percentage)

        let hasAlpha = true
        let scale: CGFloat = 0.0 // Use scale factor of main screen

        UIGraphicsBeginImageContextWithOptions(cgSize, !hasAlpha, scale)
        self.draw(in: CGRect(origin: CGPoint.zero, size: cgSize))

        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
        return scaledImage
    }

0
extension UIImage {
func resized(toValue value: CGFloat) -> UIImage {
    if size.width > size.height {
        return self.resize(toWidth: value)!
    } else {
        return self.resize(toHeight: value)!
    }
}

0

Ich war mit den Lösungen hier nicht zufrieden, die ein Bild basierend auf einer bestimmten KB-Größe erzeugen, da die meisten von ihnen verwendet wurden .jpegData(compressionQuality: x). Diese Methode funktioniert nicht mit großen Bildern, da das große Bild auch bei einer auf 0,0 eingestellten Komprimierungsqualität groß bleibt, z. B. 10 MB, die im Hochformat eines neueren iPhone erzeugt werden, immer noch über 1 MB liegen, während die Komprimierungsqualität auf 0,0 eingestellt ist.

Deshalb habe ich die Antwort von @Leo Dabus verwendet und sie in eine Hilfsstruktur umgeschrieben, die ein Bild in eine Hintergrundwarteschlange konvertiert:

import UIKit

struct ImageResizer {
    static func resize(image: UIImage, maxByte: Int, completion: @escaping (UIImage?) -> ()) {
        DispatchQueue.global(qos: .userInitiated).async {
            guard let currentImageSize = image.jpegData(compressionQuality: 1.0)?.count else { return completion(nil) }
            
            var imageSize = currentImageSize
            var percentage: CGFloat = 1.0
            var generatedImage: UIImage? = image
            let percantageDecrease: CGFloat = imageSize < 10000000 ? 0.1 : 0.3
            
            while imageSize > maxByte && percentage > 0.01 {
                let canvas = CGSize(width: image.size.width * percentage,
                                    height: image.size.height * percentage)
                let format = image.imageRendererFormat
                format.opaque = true
                generatedImage = UIGraphicsImageRenderer(size: canvas, format: format).image {
                    _ in image.draw(in: CGRect(origin: .zero, size: canvas))
                }
                guard let generatedImageSize = generatedImage?.jpegData(compressionQuality: 1.0)?.count else { return completion(nil) }
                imageSize = generatedImageSize
                percentage -= percantageDecrease
            }
            
            completion(generatedImage)
        }
    }
}

Verwendung:

        ImageResizer.resize(image: image, maxByte: 800000) { img in
            guard let resizedImage = img else { return }
            // Use resizedImage
        }
    }

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.