Avatar < 6 kB

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Bill987654321
User
Beiträge: 136
Registriert: Sonntag 8. März 2020, 10:56

Wollte mir heute einen Avatar hochladen. Deswegen habe ich ein Foto (jpg) aufgenommen und die Dateigröße reduziert. Leider war sie nach dem letzten Reduzieren immer noch größer als die erlaubten 6 kB.
Kann ich ein Foto auf weniger als 6 kB minimieren bzw. wie kreiere ich eine Datei mit einem Speicherbedarf < 6 kB in einem erlaubten Format?
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bill987654321: Bei JPEG die Grösse auf die erlaubten 80×80 Pixel reduzieren und dann die Qualität so weit runter drehen bis die Datei ≤6 KiB ist. Nicht kB — das wären noch mal 144 Bytes weniger.

Hätte jetzt nicht gedacht, dass das diese Grenze bei JPEG tatsächlich Probleme macht.

Ach, und drauf achten das da nicht noch irgendwelche Metainformationen wie Kameramodell etc. in der Datei stecken.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
Bill987654321
User
Beiträge: 136
Registriert: Sonntag 8. März 2020, 10:56

Ich bekomme es einfach nicht hin. Ich habe aus Fotos Teilbereiche herausgeschnitten, die Dateigröße verringert und in schwarz/weiß anzeigen lassen. Die Dateigröße war aber immer noch größer als 6 kiB.
Wie kann ich ein Foto auf < 6 kiB reduzieren?
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Geht auch webp?
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
Bill987654321
User
Beiträge: 136
Registriert: Sonntag 8. März 2020, 10:56

Ich glaube nicht.
Laut Support kann man folgende Dateien verwenden: jpg, png oder gif
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich habe mal ein ”Foto” genommen, das auf 80×80 Pixel verkleinert und mit verschiedenen Einstellungen gespeichert. Links Originalgrösse, rechts 3× vergrössert:
Bild
  1. 13391 Bytes verlustfrei als PNG.
  2. 10570 Bytes JPEG 100%, volle Farbinfo
  3. 5667 Bytes JPEG 96%, volle Farbinfo (Qualität solange runtergedreht bis unter 6KiB)
  4. 2097 Bytes JPEG 75%, viertel Farbinfo (Farbinfo-Menge reduziert und Qualität solange runtergedreht bis die ersten Artefakte entstanden)
Da stelle ich mir jetzt die Frage wie man es *nicht* schafft ein JPEG unter 6 KiB zu bekommen. 🤔
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Also webp sollte auf jeden Fall freigeschaltet werden. Spart Speicherplatz.
Ich bin letztens drüber gestolpert, als ich eine dieser Hypermodernen Webseiten besucht habe.
Bis vor kurzem wusste ich noch nicht einmal, dass es das Grafikformat gibt :-D
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das ist IMHO noch ein bisschen exotisch und hat bis letztes Jahr, also fast 9 Jahre gebraucht bis Firefox es unterstützt. Ich benutze ein Ubuntu LTS bei dem Gimp das nicht unterstützt. Man liest im Netz auch, dass die kleineren Grössen auch durch mehr Qualitätsverlust erreicht werden — das Details teilweise verschwommener sind als bei einem gleich grossen JPEG. Den Effekt kann man aber bei JPEG auch erreichen wenn man das Bild vorher etwas weichzeichnet um die Komprimierbarkeit für den JPEG-Algorithmus zu erhöhen. Gimp hat im entsprechenden Dialog beim exportieren als JPEG einen Schieberegler dafür.

Ich habe da so ein bisschen das Gefühl das Google das entwickelt hat um auf Teufel komm raus und ohne grosse Rücksicht auf Verluste Speicherplatz und Bandbreite zu sparen. Einmal weil das für Google selbst weniger Speicherplatz und Bandbreite bedeutet. Zum anderen ist Google auch bei allen anderen Webseiten die Geschwindigkeit in der die geladen werden können das allerhöchste Gut. Wenn man sich mal anschaut was die Webmaster-Tools als ”zu langsam” anmeckern, und dann das Verhältnis von eingebundenen Google Analytics, Ads. und Tagmanager-Kram anschaut ist das schon ein bisschen pervers. Leute macht eure Webseiten so schlank wie möglich, damit den Nutzern Googles Spyware und die Werbung beim laden nicht unangenehm auffallen.

Wenn alle hier angemeldeten Benutzer die maximalen 6 KiB ausschöpfen, dann liegen da ca. 111 MiB Daten auf dem Server. Und wenn eine Seite hier mit 15 Beiträgen voll ist, und jeder Beitrag von einem anderen Nutzer ist, und derjenige der die Seite aufruft noch keines der Avatar-Bilder im Browser-Cache hat, dann sind das sagenhafte 90 KiB die da geladen werden müssen. Wenn man ein 56k-Modem hat, fällt das vielleicht noch etwas unangenehm auf, bei DSL 1000 merkt man die Sekunde vielleicht gerade noch so, aber bei heutigen Bandbreiten‽
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Oh, ganz vergessen das hier rein zu stellen. Ein kleines, schnell zusammengehacktes Programm das ein Bild nimmt, falls nötig auf maximal 80×80 Pixel verkleinert, und dann versucht die bestmögliche Qualität für die maximalen 6KiB zu erreichen:

Code: Alles auswählen

#!/usr/bin/env python3
"""
Resizes and recompresses an image file according to the restrictions imposed by
the german Python forum.

The program first resizes and then tries PNG and JPEG with different
settings/quality values until the file size criteria is matched.  This should
give the best quality that satisfies the given restrictions.
"""
from io import BytesIO
from itertools import chain

import click
from loguru import logger
from PIL import Image, UnidentifiedImageError

ALLOWED_IMAGE_FORMATS = ["GIF", "JPEG", "PNG"]
MAX_IMAGE_SIZE = 80
MAX_FILE_SIZE = 6 * 1024


def get_resize_factor(image, max_size):
    return min(max_size / image.width, max_size / image.height, 1)


def resize_image(image, factor):
    #
    # Conversion from paletted and bitmaps to a mode that can be
    # resized with smooth resampling instead of just nearest
    # neighbours.
    #
    # TODO Here alpha information is lost if there was any! Maybe
    # handle that better.  At least emit a warning if there was
    # alpha.
    #
    if image.getpalette():
        image = image.convert("RGB")
    elif image.mode == "1":
        image = image.convert("L")

    return image.resize(
        (int(image.width * factor), int(image.height * factor)), Image.LANCZOS
    )


def convert_image_to_file_content(image, image_format, **save_options):
    file = BytesIO()
    image.save(file, image_format, optimize=True, **save_options)
    return file.getvalue()


def try_png(image):
    yield ("PNG", convert_image_to_file_content(image, "PNG"))
    #
    # TODO Try if image can be converted to "L" or "P" mode without losing
    #   information or very little information.
    #


def try_jpeg(image):
    return (
        (
            "JPEG",
            min(
                (
                    convert_image_to_file_content(
                        image, "JPEG", quality=quality, progressive=progressive
                    )
                    for progressive in [False, True]
                ),
                key=len,
            ),
        )
        for quality in reversed(range(101))
    )


@logger.catch()
@click.command()
@click.option("-o", "--output-file", type=click.File("wb"), default="-")
@click.argument("INPUT-FILE", type=click.File("rb"), default="-")
def main(input_file, output_file):
    """
    Resize and recompress image according to german Python forum restrictions
    for avatars.
    """
    logger.info("Processing {filename!r}...", filename=input_file.name)
    file_content = input_file.read()
    try:
        image = Image.open(BytesIO(file_content))
    except UnidentifiedImageError:
        logger.error("Unknown image format.")
    else:
        resize_factor = get_resize_factor(image, MAX_IMAGE_SIZE)
        if (
            resize_factor == 1
            and image.format in ALLOWED_IMAGE_FORMATS
            and len(file_content) <= MAX_FILE_SIZE
        ):
            logger.success("File already matches all criteria.")
            output_file.write(file_content)
        elif image.is_animated:
            logger.error("Not dealing with animations (yet?).")
        else:
            if resize_factor != 1:
                image = resize_image(image, resize_factor)
                assert MAX_IMAGE_SIZE in image.size
            assert get_resize_factor(image, MAX_IMAGE_SIZE) == 1

            for image_format, file_content in chain.from_iterable(
                f(image) for f in [try_png, try_jpeg]
            ):
                if len(file_content) <= MAX_FILE_SIZE:
                    logger.success(
                        "Writing {} file with {} bytes.",
                        image_format,
                        len(file_content),
                    )
                    output_file.write(file_content)
                    break
            else:
                logger.error("Could not create a file matching the criteria.")


if __name__ == "__main__":
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten