Erzwinge einen Durchschnitt für ein Bild


20

Schreiben Sie ein Programm, das ein Standard- Echtfarbenbild und eine einzelne 24-Bit- RGB- Farbe (drei Zahlen von 0 bis 255) aufnimmt . Ändern Sie das Eingabebild (oder geben Sie ein neues Bild mit denselben Abmessungen aus), sodass die durchschnittliche Farbe genau der einzelnen eingegebenen Farbe entspricht. Sie können die Pixel im Eingabebild beliebig ändern, um dies zu erreichen. Ziel ist es jedoch, die Farbänderungen so wenig wie möglich sichtbar zu machen .

Die durchschnittliche Farbe eines RGB-Bildes setzt sich aus drei arithmetischen Mitteln zusammen , eines für jeden Farbkanal. Der durchschnittliche Rotwert ist die Summe der Rotwerte aller Pixel im Bild geteilt durch die Gesamtzahl der Pixel (Bildbereich), abgerundet auf die nächste Ganzzahl. Der grüne und der blaue Durchschnitt werden auf die gleiche Weise berechnet.

Dieses Python 2- Skript (mit PIL ) kann die durchschnittliche Farbe der meisten Bilddateiformate berechnen:

from PIL import Image
print 'Enter image file'
im = Image.open(raw_input()).convert('RGB')
pixels = im.load()
avg = [0, 0, 0]
for x in range(im.size[0]):
    for y in range(im.size[1]):
        for i in range(3):
            avg[i] += pixels[x, y][i]
print 'The average color is', tuple(c // (im.size[0] * im.size[1]) for c in avg)

(Es gibt ähnliche durchschnittliche Farbprogramme hier , aber sie müssen nicht genau die gleiche Berechnung tun.)

Die Hauptanforderung für Ihr Programm besteht darin, dass für jedes Eingabebild die durchschnittliche Farbe der entsprechenden Ausgabe genau mit der eingegebenen Farbe übereinstimmen muss. Dies wird anhand des Python-Snippets oder eines entsprechenden Codes beurteilt. Das Ausgabebild muss genau die gleichen Abmessungen wie das Eingabebild haben.

Sie könnten also technisch ein Programm einreichen, das einfach die gesamte Eingabe mit der angegebenen Durchschnittsfarbe einfärbt (weil der Durchschnitt immer diese Farbe sein würde), aber dies ist ein Beliebtheitswettbewerb - die Einreichung mit der höchsten Stimmenzahl gewinnt und eine solche Kleinigkeit Einreichung wird Ihnen nicht viele positive Stimmen einbringen. Neuartige Ideen wie das Ausnutzen von Macken in der menschlichen Sicht oder das Verkleinern des Bildes und das Zeichnen eines farbigen Rahmens werden (hoffentlich) zu Abstimmungen führen.

Beachten Sie, dass bestimmte Kombinationen von Durchschnittsfarben und Bildern äußerst auffällige Farbänderungen erfordern. Wenn zum Beispiel die zu vergleichende Durchschnittsfarbe schwarz (0, 0, 0) wäre, müsste jedes Eingabebild vollständig schwarz gemacht werden, denn wenn Pixel Werte ungleich Null hätten, würden sie auch den Durchschnittswert ungleich Null machen ( Rundungsfehler vorbehalten). Beachten Sie diese Einschränkungen bei der Abstimmung.

Bilder testen

Einige Bilder und ihre durchschnittlichen Standardfarben zum Herumspielen. Klicken Sie für volle Größen.

A. Durchschnitt (127, 127, 127)

Von fejesjoco ‚s Bilder mit allen Farben beantworten . Gefunden Original auf seinem Blog .

B. durchschnittlich (62, 71, 73)

Yokohama . Bereitgestellt von Geobits .

C. Durchschnitt (115, 112, 111)

Tokio . Bereitgestellt von Geobits .

D. Durchschnitt (154, 151, 154)

Eschers Wasserfall . Original .

E. Durchschnitt (105, 103, 102)

Mount Shasta . Von mir bereitgestellt.

F. Durchschnitt (75, 91, 110)

Die Sternreiche Nacht

Anmerkungen

  • Die genauen Eingabe- und Ausgabeformate und Bilddateitypen, die Ihr Programm verwendet, spielen keine große Rolle. Stellen Sie einfach sicher, dass klar ist, wie Sie Ihr Programm verwenden.
  • Es ist wahrscheinlich eine gute Idee (aber technisch keine Voraussetzung), dass ein Bild, wenn es bereits die durchschnittliche Zielfarbe hat, so ausgegeben wird, wie es ist.
  • Stellen Sie Testbilder mit einem durchschnittlichen Farbeintrag als (150, 100, 100) oder (75, 91, 110) bereit, damit die Wähler dieselben Eingaben für verschiedene Lösungen sehen können. (Das Posten von mehr Beispielen ist in Ordnung, sogar erwünscht.)

2
Die Teilnehmer können die Eingabefarben auswählen, mit denen sie die Effektivität ihrer Lösung demonstrieren. Macht es das den Leuten nicht schwer, die Lösungen zu vergleichen? Im Extremfall könnte jemand Eingabefarben wählen, die dem Durchschnitt des Bildes sehr ähnlich sind, und es würde so aussehen, als wäre ihre Lösung sehr effektiv.
Reto Koradi

1
@ vihan1086 Wenn ich das richtig verstanden habe, wird die durchschnittliche Farbe als 24-Bit-RGB-Farbeingabe bereitgestellt, die nicht aus einem Eingabebild stammt.
Trichoplax

3
Es könnte interessant sein, die Interpretation von @ vihan1086 zu verwenden und die Beispielbilder als Quelle für Eingabefarben zu verwenden, damit ein Bild in der Durchschnittsfarbe eines anderen angezeigt wird. Auf diese Weise können unterschiedliche Antworten fair verglichen werden.
Trichoplax

Das Hauptproblem dabei ist, dass die meisten von ihnen einen Durchschnitt haben, der sehr nahe am Grau liegt. Sternennacht ist wahrscheinlich die am weitesten entfernte, aber der Rest ist durchschnittlich.
Geobits

@RetoKoradi Hoffentlich sind die Wähler klug genug, um solche Dinge zu berücksichtigen, obwohl ich einen Hinweis hinzugefügt habe, welche durchschnittlichen Standardfarben verwendet werden sollen.
Calvins Hobbys

Antworten:


11

Python 2 + PIL, einfache Farbskalierung

from PIL import Image
import math

INFILE = "street.jpg"
OUTFILE = "output.png"
AVERAGE = (150, 100, 100)

im = Image.open(INFILE)
im = im.convert("RGB")
width, height = prev_size = im.size
pixels = {(x, y): list(im.getpixel((x, y)))
          for x in range(width) for y in range(height)}

def get_avg():
    total_rgb = [0, 0, 0]

    for x in range(width):
        for y in range(height):
            for i in range(3):
                total_rgb[i] += int(pixels[x, y][i])

    return [float(x)/(width*height) for x in total_rgb]

curr_avg = get_avg()

while tuple(int(x) for x in curr_avg) != AVERAGE:
    print curr_avg   
    non_capped = [0, 0, 0]
    total_rgb = [0, 0, 0]

    for x in range(width):
        for y in range(height):
            for i in range(3):
                if curr_avg[i] < AVERAGE[i] and pixels[x, y][i] < 255:
                    non_capped[i] += 1
                    total_rgb[i] += int(pixels[x, y][i])

                elif curr_avg[i] > AVERAGE[i] and pixels[x, y][i] > 0:
                    non_capped[i] += 1
                    total_rgb[i] += int(pixels[x, y][i])

    ratios = [1 if z == 0 else
              x/(y/float(z))
              for x,y,z in zip(AVERAGE, total_rgb, non_capped)]

    for x in range(width):
        for y in range(height):
            col = []

            for i in range(3):
                new_col = (pixels[x, y][i] + 0.01) * ratios[i]
                col.append(min(255, max(0, new_col)))

            pixels[x, y] = tuple(col)

    curr_avg = get_avg()

print curr_avg

for pixel in pixels:
    im.putpixel(pixel, tuple(int(x) for x in pixels[pixel]))

im.save(OUTFILE)

Hier ist ein naiver Ansatz, der als gute Basis dienen sollte. Bei jeder Iteration vergleichen wir unseren aktuellen Durchschnitt mit dem gewünschten Durchschnitt und skalieren den RGB-Wert jedes Pixels anhand des entsprechenden Verhältnisses. Wir müssen jedoch aus zwei Gründen vorsichtig sein:

  • Das Skalieren von 0 führt immer noch zu 0, also fügen wir vor dem Skalieren etwas Kleines hinzu (hier 0.01 )

  • RGB-Werte liegen zwischen 0 und 255, daher müssen wir das Verhältnis entsprechend anpassen, um die Tatsache auszugleichen, dass das Skalieren von Pixeln mit Begrenzung nichts bewirkt.

Die Bilder werden als PNG gespeichert, da das Speichern als JPG die Farbdurchschnitte durcheinander zu bringen scheint.

Beispielausgabe

(40, 40, 40)

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

(150, 100, 100)

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

(75, 91, 110), Starry Night-Palette

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben


2
Sie möchten auf jeden Fall ein Bildformat mit verlustfreier Komprimierung verwenden. JPEG ist also keine gute Option.
Reto Koradi

Sie können sich immer auf Sp für coole Bildherausforderungslösungen verlassen.
Alex A.

6

C ++, Gammakorrektur

Dies führt eine Helligkeitsanpassung des Bildes mit einer einfachen Gammakorrektur durch, wobei der Gammawert für jede Komponente separat bestimmt wird, um dem Zielmittelwert zu entsprechen.

Die übergeordneten Schritte sind:

  1. Lesen Sie das Bild und extrahieren Sie das Histogramm für jede Farbkomponente.
  2. Führen Sie für jede Komponente eine binäre Suche des Gammawerts durch. Die Gammawerte werden binär durchsucht, bis das resultierende Histogramm den gewünschten Durchschnitt aufweist.
  3. Lesen Sie das Bild ein zweites Mal und wenden Sie die Gammakorrektur an.

Alle Bildeingaben / -ausgaben verwenden PPM-Dateien in ASCII. Bilder wurden mit GIMP von / nach PNG konvertiert. Der Code wurde auf einem Mac ausgeführt, Bildkonvertierungen wurden unter Windows durchgeführt.

Code:

#include <cmath>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <iostream>

static inline int mapVal(int val, float gamma)
{
    float relVal = (val + 1.0f) / 257.0f;
    float newRelVal = powf(relVal, gamma);

    int newVal = static_cast<int>(newRelVal * 257.0f - 0.5f);
    if (newVal < 0)
    {
        newVal = 0;
    }
    else if (newVal > 255)
    {
        newVal = 255;
    }

    return newVal;
}

struct Histogram
{
    Histogram();

    bool read(const std::string fileName);
    int getAvg(int colIdx) const;
    void adjust(const Histogram& origHist, int colIdx, float gamma);

    int pixCount;
    std::vector<int> freqA[3];
};

Histogram::Histogram()
  : pixCount(0)
{
    for (int iCol = 0; iCol < 3; ++iCol)
    {
        freqA[iCol].resize(256, 0);
    }
}

bool Histogram::read(const std::string fileName)
{
    for (int iCol = 0; iCol < 3; ++iCol)
    {
        freqA[iCol].assign(256, 0);
    }

    std::ifstream inStrm(fileName);

    std::string format;
    inStrm >> format;
    if (format != "P3")
    {
        std::cerr << "invalid PPM header" << std::endl;
        return false;
    }

    int w = 0, h = 0;
    inStrm >> w >> h;
    if (w <= 0 || h <= 0)
    {
        std::cerr << "invalid size" << std::endl;
        return false;
    }

    int maxVal = 0;
    inStrm >> maxVal;
    if (maxVal != 255)
    {
        std::cerr << "invalid max value (255 expected)" << std::endl;
        return false;
    }

    pixCount = w * h;

    int sumR = 0, sumG = 0, sumB = 0;
    for (int iPix = 0; iPix < pixCount; ++iPix)
    {
        int r = 0, g = 0, b = 0;
        inStrm >> r >> g >> b;
        ++freqA[0][r];
        ++freqA[1][g];
        ++freqA[2][b];
    }

    return true;
}

int Histogram::getAvg(int colIdx) const
{
    int avg = 0;
    for (int val = 0; val < 256; ++val)
    {
        avg += freqA[colIdx][val] * val;
    }

    return avg / pixCount;
}

void Histogram::adjust(const Histogram& origHist, int colIdx, float gamma)
{
    freqA[colIdx].assign(256, 0);

    for (int val = 0; val < 256; ++val)
    {
        int newVal = mapVal(val, gamma);
        freqA[colIdx][newVal] += origHist.freqA[colIdx][val];
    }
}

void mapImage(const std::string fileName, float gammaA[])
{
    std::ifstream inStrm(fileName);

    std::string format;
    inStrm >> format;

    int w = 0, h = 0;
    inStrm >> w >> h;

    int maxVal = 0;
    inStrm >> maxVal;

    std::cout << "P3" << std::endl;
    std::cout << w << " " << h << std::endl;
    std::cout << "255" << std::endl;

    int nPix = w * h;

    for (int iPix = 0; iPix < nPix; ++iPix)
    {
        int inRgb[3] = {0};
        inStrm >> inRgb[0] >> inRgb[1] >> inRgb[2];

        int outRgb[3] = {0};
        for (int iCol = 0; iCol < 3; ++iCol)
        {
            outRgb[iCol] = mapVal(inRgb[iCol], gammaA[iCol]);
        }

        std::cout << outRgb[0] << " " << outRgb[1] << " "
                  << outRgb[2] << std::endl;
    }
}

int main(int argc, char* argv[])
{
    if (argc < 5)
    {
        std::cerr << "usage: " << argv[0]
                  << " ppmFileName targetR targetG targetB"
                  << std::endl;
        return 1;
    }

    std::string inFileName = argv[1];

    int targAvg[3] = {0};
    std::istringstream strmR(argv[2]);
    strmR >> targAvg[0];
    std::istringstream strmG(argv[3]);
    strmG >> targAvg[1];
    std::istringstream strmB(argv[4]);
    strmB >> targAvg[2];

    Histogram origHist;
    if (!origHist.read(inFileName))
    {
        return 1;
    }

    Histogram newHist(origHist);
    float gammaA[3] = {0.0f};

    for (int iCol = 0; iCol < 3; ++iCol)
    {
        float minGamma = 0.0f;
        float maxGamma = 1.0f;
        for (;;)
        {
            newHist.adjust(origHist, iCol, maxGamma);
            int avg = newHist.getAvg(iCol);
            if (avg <= targAvg[iCol])
            {
                break;
            }
            maxGamma *= 2.0f;
        }

        for (;;)
        {
            float midGamma = 0.5f * (minGamma + maxGamma);

            newHist.adjust(origHist, iCol, midGamma);
            int avg = newHist.getAvg(iCol);
            if (avg < targAvg[iCol])
            {
                maxGamma = midGamma;
            }
            else if (avg > targAvg[iCol])
            {
                minGamma = midGamma;
            }
            else
            {
                gammaA[iCol] = midGamma;
                break;
            }
        }
    }

    mapImage(inFileName, gammaA);

    return 0;
}

Der Code selbst ist ziemlich einfach. Ein subtiles, aber wichtiges Detail ist, dass ich die Farbwerte, obwohl sie im Bereich [0, 255] liegen, der Gammakurve so zuordne, als ob der Bereich [-1, 256] wäre. Dadurch kann der Durchschnitt auf 0 oder 255 gesetzt werden. Andernfalls würde 0 immer 0 bleiben und 255 würde immer 255 bleiben, was möglicherweise niemals einen Durchschnitt von 0/255 zulässt.

Benutzen:

  1. Speichern Sie den Code in einer Datei mit der Erweiterung .cpp, z force.cpp.
  2. Kompilieren mit c++ -o force -O2 force.cpp.
  3. Laufen Sie mit ./force input.ppm targetR targetG target >output.ppm.

Beispielausgabe für 40, 40, 40

Beachten Sie, dass die Bilder für alle größeren Samples als JPEGs enthalten sind, da sie als PNGs die SE-Größenbeschränkung überschreiten. Da JPEG ein verlustbehaftetes Komprimierungsformat ist, entsprechen sie möglicherweise nicht genau dem Zieldurchschnitt. Ich habe die PNG-Version aller Dateien, die genau übereinstimmt.

Af1 Bf1 Cf1 Df1 Ef1 Ff1

Beispielausgabe für 150, 100, 100:

Af2 Bf2 Cf2 Df2 Ef2 Ff2

Beispielausgabe für 75, 91, 110:

Af3 Bf3 Cf3 Df3 Ef3 Ff3


Ich musste die anderen Bilder verkleinern, um das Limit zu erreichen - vielleicht versuchen Sie das?
Sp3000,

@ Sp3000 Ok, jetzt sind alle Bilder enthalten. Jetzt auch mit Thumbnails. Am Ende habe ich die JPEG-Version für die großen verwendet. Einer von ihnen hat die Größenbeschränkung zwar unterschritten, scheint aber automatisch in JPEG konvertiert worden zu sein. Das erste und letzte Beispiel sind noch PNGs.
Reto Koradi

2

Python 2 + PIL

from PIL import Image
import random
import math

SOURCE = 'input.png'
OUTPUT = 'output.png'
AVERAGE = [150, 100, 100]

im = Image.open(SOURCE).convert('RGB')
pixels = im.load()
w = im.size[0]
h = im.size[1]
npixels = w * h

maxdiff = 0.1

# for consistent results...
random.seed(42)
order = range(npixels)
random.shuffle(order)

def calc_sum(pixels, w, h):
    sums = [0, 0, 0]
    for x in range(w):
        for y in range(h):
            for i in range(3):
                sums[i] += pixels[x, y][i]
    return sums

def get_coordinates(index, w):
    return tuple([index % w, index // w])

desired_sums = [AVERAGE[0] * npixels, AVERAGE[1] * npixels, AVERAGE[2] * npixels]

sums = calc_sum(pixels, w, h)
for i in range(3):
    while sums[i] != desired_sums[i]:
        for j in range(npixels):
            if sums[i] == desired_sums[i]:
                break
            elif sums[i] < desired_sums[i]:
                coord = get_coordinates(order[j], w)
                pixel = list(pixels[coord])
                delta = int(maxdiff * (255 - pixel[i]))
                if delta == 0 and pixel[i] != 255:
                    delta = 1
                delta = min(delta, desired_sums[i] - sums[i])

                sums[i] += delta
                pixel[i] += delta
                pixels[coord] = tuple(pixel)
            else:
                coord = get_coordinates(order[j], w)
                pixel = list(pixels[coord])
                delta = int(maxdiff * pixel[i])
                if delta == 0 and pixel[i] != 0:
                    delta = 1
                delta = min(delta, sums[i] - desired_sums[i])

                sums[i] -= delta
                pixel[i] -= delta
                pixels[coord] = tuple(pixel)

# output image
for x in range(w):
    for y in range(h):
        im.putpixel(tuple([x, y]), pixels[tuple([x, y])])

im.save(OUTPUT)

Dies durchläuft jedes Pixel in einer zufälligen Reihenfolge und verringert den Abstand zwischen jeder Komponente der Farbe des Pixels und / 255oder 0(abhängig davon, ob der aktuelle Durchschnitt kleiner oder größer als der gewünschte Durchschnitt ist). Der Abstand wird um einen festen Multiplikationsfaktor verringert. Dies wird wiederholt, bis der gewünschte Durchschnitt erreicht ist. Die Reduzierung erfolgt immer mindestens 1, es sei denn, die Farbe ist 255(oder 0), um sicherzustellen, dass die Verarbeitung nicht unterbrochen wird, sobald sich das Pixel in der Nähe von Weiß oder Schwarz befindet.

Beispielausgabe

(40, 40, 40)

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

(150, 100, 100)

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

(75, 91, 110)

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben


1

Java

Ein RNG-basierter Ansatz. Ein bisschen langsam für große Eingabebilder.

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.*;

import javax.imageio.ImageIO;


public class Averager {
    static Random r;
    static long sigmaR=0,sigmaG=0,sigmaB=0;
    static int w,h;
    static int rbar,gbar,bbar;
    static BufferedImage i;
    private static File file;
    static void upRed(){
        int x=r.nextInt(w);
        int y=r.nextInt(h);
        Color c=new Color(i.getRGB(x, y));
        if(c.getRed()==255)return;
        sigmaR++;
        c=new Color(c.getRed()+1,c.getGreen(),c.getBlue());
        i.setRGB(x, y,c.getRGB());
    }
    static void downRed(){
        int x=r.nextInt(w);
        int y=r.nextInt(h);
        Color c=new Color(i.getRGB(x, y));
        if(c.getRed()==0)return;
        sigmaR--;
        c=new Color(c.getRed()-1,c.getGreen(),c.getBlue());
        i.setRGB(x, y,c.getRGB());
    }
    static void upGreen(){
        int x=r.nextInt(w);
        int y=r.nextInt(h);
        Color c=new Color(i.getRGB(x, y));
        if(c.getGreen()==255)return;
        sigmaG++;
        c=new Color(c.getRed(),c.getGreen()+1,c.getBlue());
        i.setRGB(x, y,c.getRGB());
    }
    static void downGreen(){
        int x=r.nextInt(w);
        int y=r.nextInt(h);
        Color c=new Color(i.getRGB(x, y));
        if(c.getGreen()==0)return;
        sigmaG--;
        c=new Color(c.getRed(),c.getGreen()-1,c.getBlue());
        i.setRGB(x,y,c.getRGB());
    }
    static void upBlue(){
        int x=r.nextInt(w);
        int y=r.nextInt(h);
        Color c=new Color(i.getRGB(x, y));
        if(c.getBlue()==255)return;
        sigmaB++;
        c=new Color(c.getRed(),c.getGreen(),c.getBlue()+1);
        i.setRGB(x, y,c.getRGB());
    }
    static void downBlue(){
        int x=r.nextInt(w);
        int y=r.nextInt(h);
        Color c=new Color(i.getRGB(x, y));
        if(c.getBlue()==0)return;
        sigmaB--;
        c=new Color(c.getRed(),c.getGreen(),c.getBlue()-1);
        i.setRGB(x,y,c.getRGB());
    }
    public static void main(String[]a) throws Exception{
        Scanner in=new Scanner(System.in);
        i=ImageIO.read(file=new File(in.nextLine()));
        rbar=in.nextInt();
        gbar=in.nextInt();
        bbar=in.nextInt();
        w=i.getWidth();
        h=i.getHeight();
        final int npix=w*h;
        r=new Random(npix*(long)i.hashCode());
        for(int x=0;x<w;x++){
            for(int y=0;y<h;y++){
                Color c=new Color(i.getRGB(x, y));
                sigmaR+=c.getRed();
                sigmaG+=c.getGreen();
                sigmaB+=c.getBlue();
            }
        }
        while(sigmaR/npix<rbar){
            upRed();
        }
        while(sigmaR/npix>rbar){
            downRed();
        }
        while(sigmaG/npix<gbar){
            upGreen();
        }
        while(sigmaG/npix>gbar){
            downGreen();
        }
        while(sigmaB/npix<bbar){
            upBlue();
        }
        while(sigmaB/npix>bbar){
            downBlue();
        }
        String k=file.getName().split("\\.")[0];
        ImageIO.write(i,"png",new File(k="out_"+k+".png"));
    }
}

Tests:

(40,40,40)

Bildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingeben

(150, 100, 100)

Bildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingeben

(75,91,110)

Bildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingebenBildbeschreibung hier eingeben

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.