Des images comme des boîtes - que contient-il? Signaler dans Yandex

Les photos et les vidéos sont des «boîtes noires», à l'intérieur desquelles il y a beaucoup d'intéressantes et d'incompréhensibles. Mais vous pouvez regarder à l'intérieur de certains formats, tout changer et voir ce qui se passe.

Polina Gurtovaya de la société Evil Martians a pris la parole lors de notre conférence  Frontend en février. Avec l'aide de l'expérience, Polina a découvert comment transformer des images simples en «images efficaces» avec des métriques. Les outils qui peuvent le faire pour nous, Polina a examiné plus près de la fin du rapport. Le résultat a été une grande excursion dans l'intérieur et les principes de fonctionnement de différents formats: du PNG et JPEG à AV1 et exotique.


- Bonjour à tous. Je m'appelle Polina, je suis le chef de file de la compagnie "Evil Martians".

Peut-être connaissez-vous des Martiens de nos nombreuses sources ouvertes. Je te parlerai un peu de lui plus tard. Et je dois probablement dire que nous développons toujours des produits, et pas seulement en sciant l'open source.



Le matériel pour le rapport sera à votre disposition via un merveilleux lien dans le référentiel sur GitHub.



Parlons un peu d'optimisation. Lorsque nous traitons avec eux, le problème est qu'ils fonctionnent bien si nous comprenons ce que nous faisons. Si on ne comprend pas, ça tourne mal. En ce qui concerne l'optimisation d'image, malheureusement, tout ici n'est vraiment pas vraiment cool. Nous n'optimiserons peut-être pas du tout les images, puis il y aura des monstres de deux mètres sur la prod, tout est triste et triste.

Si nous optimisons, que faisons-nous? Nous pensons: ici nous avons une image, c'est une sorte de boîte noire mystérieuse, et le programme d'optimisation fait quelque chose avec cette image, une sorte de chamanisme noir. La qualité d'optimisation que nous obtenons est un peu douteuse.



Regardons un exemple. J'ai un chat au format PNG. Je pense que nous devons l'optimiser. Que suis-je en train de faire? Je crée une version WebP et mets soigneusement les deux images dans une balise <picture>. Pensez-vous que j'ai bien fait ici ou non? Pourquoi y a-t-il si peu de mains? Je suis vraiment bien fait!

J'ai tout fait correctement, mais la version WebP s'est avérée deux kilo-octets de plus que l'original. Ce n'est pas du tout ce que je voulais.




Une autre optimisation, essayez le numéro 2. J'ai un petit conteneur sur la page et un gros, gros chat. Je veux mettre un gros chat dans un petit récipient. Que suis-je en train de faire? Je fais un redimensionnement car il est stupide de conduire des octets sur le réseau si la taille de mon conteneur est petite. Bien sûr, je prends en compte le ratio de pixels de l'appareil de mon appareil. Pensez-vous que je vais bien ici ou non? J'ai fini! Et regardez ce que j'ai fait.

J'utilise la bibliothèque libvips. Elle est très cool et populaire, et de mon énorme chat léger mais heureux j'ai eu un petit chat très lourd. Le sceau a augmenté de 2,5 fois (en octets) pendant le redimensionnement (en pixels) vers le bas. Cool, ouais?



En général, pour que cela ne nous arrive pas, que nous comprenions comment optimiser nos images pour notre tâche, et, en général, pour que nous comprenions au moins ce qui se passe, regardons dans la boîte et comprenons ce qu'il y a à l'intérieur.



Commençons par regarder un format aussi intéressant que PNG. Autour de chaque site, un petit peengshechka est caché quelque part. Cette fois. Par conséquent, ils doivent être compris. Deuxièmement: PNG - format de compression sans perte. Cela signifie que nous garantissons une correspondance parfaite avec l'original en pixels, mais en même temps, hélas, nous sommes limités par nature, nous ne pouvons pas compresser moins que la quantité.



Peengeshka se replie dans un conteneur, comme n'importe quel format d'image. L'une des premières choses que nous devons dire au programme s'il lit tout est ce qui se trouve à l'intérieur. Si vous supposez que vos décodeurs déterminent les images par extension, ce n'est pas le cas.

Pengashka rapporte qu'il s'agit de PNG, les huit premiers octets de son conteneur. Il dit «PNG». De plus - encore une fois, cela est caractéristique de tout conteneur - vous avez une disposition des morceaux. Autrement dit, les informations sont regroupées en morceaux, elles sont en quelque sorte organisées. Comment - définit le conteneur. En PNG, cela ressemble à ceci: vous avez quatre octets qui sont responsables de la longueur et quatre octets qui sont responsables du type de bloc. Quels types - nous parlerons un peu plus tard. 

Si le morceau a une longueur non nulle, il a une charge utile. De plus, il existe une somme de contrôle. Vous vérifiez si quelque chose y a été battu. Viennent ensuite les morceaux suivants.



Analyser non seulement un fichier PNG, mais presque n'importe lequel est assez facile. Prenez FileReader, c'est une API de navigateur. Nous lisons le fichier à l'aide de FileReader. Dès que nous lisons, nous coupons ce fichier en morceaux. Je ne donnerai pas ici le code de la fonction split to chunks, mais vous pouvez deviner qu'il existe une combinaison complexe de si et pour. 




D'accord, nous l'avons coupé, nous verrons ce qui se passe. Nous avons plusieurs types de morceaux, et ils sont très, très caractéristiques de presque tous les formats. Le premier est appelé IHDR. Il existe un certain nombre de morceaux appelés IDAT. Ces noms peuvent vous sembler un peu étranges, mais nous allons maintenant comprendre de quoi il s'agit. Quand tout se termine, nous voyons le morceau de fin.



Examinons de plus près l'intérieur des morceaux. L'IHDR est un méta-morceau, et presque toutes les images ont un tel méta-morceau. On l'appelle différemment, on l'arrange différemment, mais c'est très probablement. Sans cela, votre décompresseur - une chose qui vous montre peengeshki ou non peengeshki - ne peut rien vous montrer. Qu'est-ce qui se trouve dans ce morceau? Encore une fois, le contenu est typique de la plupart des formats. C'est la hauteur et la largeur. La hauteur et la largeur sont cousues dans votre dossier, cela vous vient. Ensuite, les indicateurs de panache typiques: bitDepth, colorType et entrelacement. 



Avant de parler de la signification de ces drapeaux et de la raison pour laquelle ils sont si, très importants pour nous, voyons comment nous stockons les pixels dans les pangshes. Dans les peaneshs, les pixels sont stockés dans un bloc appelé IDAT. Dans un bon scénario, les pixels sont un certain nombre de nombres qui sont regroupés dans un bloc, et ce bloc est compressé par l'algorithme de compression Deflate. Qui a utilisé l'algorithme de compression Deflate? D'accord, à quand remonte la dernière fois que vous avez zippé quelque chose? Savez-vous que Deflate est gzip? Je pense donc que beaucoup l'ont utilisé.

Mais dans peengeshah, une autre chose intéressante apparaît qui est utilisée dans un grand nombre de formats, mais probablement dans tous. Ce gizmo est appelé codage prédictif. Le fait est que nos images ne sont pas des pixels aléatoires. Ce qui est peint sur notre petite image est en quelque sorte lié les uns aux autres. Il y a des zones sombres, des zones claires, etc.

Nous essayons d'exploiter ce fait, et au lieu de stocker la valeur de pixel dans ces cellules bleues, nous essayons de prédire ces pixels sur la base des précédents. En PNG, ces prédictions sont très simples et elles sont regroupées dans le tout premier octet avant la ligne avec les pixels. Une prédiction peut être comme ça, par exemple, ne prédisons rien et mettons tout simplement tel quel. Ou, par exemple, nous pouvons dire ceci: mais ne gardons que la différence entre le pixel actuel et le précédent.

Si vous avez la même couleur dans votre ligne, vous aurez tous les zéros, tout est parfaitement compressé, c'est très cool.



Mais maintenant, parlons de ce que signifie réellement un pixel. Un pixel apparaît dans un peengesh sous forme de nombre. En manipulant le nombre de nombres, vous pouvez compresser très, très étroitement votre PNG - trois fois.

Quelles sont les options? Le premier est True Color et alpha. Nous avons trois canaux, trois couleurs, trois numéros par couleur. Plus un canal qui est responsable de la transparence.

La taille de ce chiffre en bits est bitDepth, le même indicateur que nous avons vu dans le bloc IHDR. Plus votre bitDepth est petit, plus le fichier est petit, mais moins vous pouvez lui présenter de couleurs. Un nombre typique est 8. Combien ça coûte? À mon avis, il y aura 16 millions avec quelque chose.

D'accord, la première optimisation que vous pouvez faire est de jeter les canaux alpha dans votre peengesh. Ce sera un colorType différent.

Vous pouvez optimiser encore mieux et utiliser un seul au lieu de quatre nombres. Mais le problème est que votre peengeshka doit être en noir et blanc.

Si vous ne voulez toujours qu'un seul numéro et laissez les couleurs, cela peut également être fait. Que se passe t-il ici? Vous prenez toutes les couleurs à l'intérieur de votre peengeshka et les coupez en un morceau séparé. Appelez cela une palette. Plus à l'intérieur de l'échantillon, qui est responsable du pixel à l'intérieur du bloc IDAT, vous stockez simplement l'index de cette palette. Si vous avez une capture d'écran sans arrière-plan complexe ou dessin, cette chose est parfaite. Elle serre peengeshki à droite wow!

Une autre chose importante à dire est l'entrelacement. Qu'est-ce que l'entrelacement? C'est à ce moment que vous expédiez votre peengeshka progressivement. Vous n'avez pas un peengeshka, mais plusieurs images. Chaque image est appelée numérisation.



Dans le même temps, à l'intérieur de la paengashka, vous triez les pixels de telle sorte que certains pixels soient arrachés des images, une image vient d'endroits spéciaux. La partie suivante en est une autre et ainsi de suite. Une technique apparemment cool comme le JPEG progressif.

Mais ça ressemble à ça. Je ne sais pas si vous voulez que vos utilisateurs voient cela, bien que cela puisse être utile pour votre tâche.

Le deuxième problème très grave du PNG entrelacé est que dès que vous entrelacez votre peengeshka, la taille de votre peengeshka devient plus grande. Et plus faible, quelque part dans quelques kilo-octets, votre peengeshka de six kilo-octets augmentera si vous désactivez Interlaced. Par conséquent, réfléchissez bien si vous le souhaitez ou non.



Nous avons parlé uniquement de PNG, mais de cette chose, vous pouvez tirer des conclusions importantes et utiles. Première conclusion: la taille de votre fichier, vous ne le croirez pas, dépend de ce qui y est dessiné. Le carré noir rétrécit mieux que le chat, je ne donnerai aucune recommandation ici. Deuxièmement, plus important: la taille de votre fichier dépend beaucoup de l'encodeur et de ses paramètres que vous transférez.

Si vous voulez voir comment fonctionnent les horribles encodeurs, utilisez ceux du navigateur. Comment c'est fait? Prenez le fichier PNG, dessinez-le sur le canevas, puis cliquez sur Enregistrer sous et comparez ce qui s'est passé avec ce qui s'est passé. En général, Chrome augmentera la taille de votre fichier de 2,5 fois, Firefox - de 1,6.

Soit dit en passant, cela dépend aussi toujours du format, c'est-à-dire que non seulement PNG doit être utilisé. Comprenons pourquoi tout dépend du format et des options intéressantes que nous avons encore.



Pour ce faire, nous parlerons de la technologie des anciens, du JPEG. Vous ne pouvez bien sûr pas minimiser l'importance du JPEG. On les trouve partout. Ils sont tellement cool, bons et encore plus, les phoques en JPEG sont une histoire assez courante. Mais JPEG est une chose plutôt compliquée, et elle est compliquée du fait que JPEG est une compression avec perte. De plus, JPEG est toujours une compression avec perte. La qualité JPEG 100% se comprime toujours avec perte.

Comment obtenir une compression avec perte? Très simple. Nous prenons une source, en supprimons les données, puis compressons sans perte. Autrement dit, plus une étape.



Voyons comment nous faisons des pertes dans nos JPEG. Donc, vous avez un chat d'une taille de 32 par 32. Pour que nous puissions faire le premier pas avec des pertes, nous devons changer nos canaux. Habituellement, nous parlons d'images en termes de RVB. Mais nous percevons les couleurs un peu complexes. Notre cerveau est généralement un gros problème, bien qu'il nous aide beaucoup à compresser le JPEG.

Nous percevons très bien le noir et le blanc. Même si vous regardez attentivement, vous remarquerez que les détails de l'image en noir et blanc se distinguent mieux. Nous venons de mettre cette image en noir et blanc dans un canal séparé. Cela s'appelle Y. En fait, la barre en Y. Nous ne faisons rien avec lui, nous le laissons tel quel.

Il existe deux autres canaux responsables de la couleur. Ce sont CB et CR. Avec ces chaînes, nous pouvons déjà nous amuser un peu. Ici, avec ces canaux, nous produisons une telle procédure cool appelée Downsampling. Nous prenons et réduisons la résolution de ce canal. Pour JPEG, il est typique de diviser par deux. Autrement dit, vous obtenez trois photos - une originale et deux moitié autant. Hourra!

Que faisons-nous ensuite? Nous ne compressons pas JPEG, pas comme un fichier entier. Nous le décomposons en blocs et compressons davantage, nous commençons déjà des blocs. Les blocs en JPEG mesurent 8 x 8 et voient ce qui leur arrive. Regardons simplement le canal Y. CB et CR sont tous les mêmes.



Ainsi, un bloc n'est pas une image, mais des chiffres. Nous devons faire des pertes en JPEG. Ce bloc mesure 8 x 8, 64 pixels, lequel jeter? Celui de gauche, celui de droite, celui du milieu? Pas clair. Mais il y a des mathématiques sympas qui nous permettent de résoudre ce problème.

Ce calcul s'appelle - maintenant, ne vous inquiétez pas si quelqu'un se souvient du terrible passé institutionnel - la transformation discrète en cosinus. Ainsi, à l'aide de cette transformée en cosinus discrète, vous pouvez convertir ces nombres dans votre bloc afin qu'ils soient importants et sans importance parmi eux.

Important: après la conversion, des nombres importants restent dans la partie supérieure gauche du bloc. En bas à droite restent des chiffres sans importance.

Ensuite, vous devez faire votre perte JPEG. C'est aussi très facile à faire. Cette astuce est appelée quantification. Désolé si vous voulez dormir maintenant, mais c'est important, croyez-moi. Donc, cette quantification même fonctionne d'une manière assez simple. Vous prenez votre bloc et une plaque spécialement conçue. Cette plaque est déterminée par votre programme d'encodeur. Ces nombres qui se sont avérés dans votre bloc, vous les divisez par ce terme de plaque par nombre et entier. Qu'obtenez-vous en conséquence?

Étant donné que les nombres sont grands dans la partie inférieure droite de la plaque, il n'y aura que des zéros.



Et en même temps votre JPEG, votre bloc se compressera parfaitement. Vous aurez un petit nombre de chiffres que vous contournerez dans un zigzag si complexe, les zéros disparaîtront tous et, bravo, notre bloc est prêt pour la compression. Ensuite, nous avons juste besoin de le compresser avec un algorithme de compression sans perte. JPEG utilise le codage Huffman, quel qu'il soit.



Comment est-il emballé dans un conteneur? Les conteneurs JPEG ont l'air un peu stupides, j'en ai peur. Parce que vous voyez les deux premiers octets et que c'est probablement JPEG. Mais jusqu'à présent, ce n'est pas clair.

Ensuite, vous devez rechercher deux méta-morceaux. Pourquoi deux? Parce que JPEG est un très large ensemble de normes différentes. Ce que nous appelons JPEG est, en règle générale, appelé JIFF. Il s'agit d'une extension spéciale de la norme JPEG. Je ne continuerai pas plus loin - en général, il y a deux méta morceaux, croyez-moi. Ces méta-morceaux contiennent des informations sur la largeur et la hauteur de votre fichier et la version de JPEG. Imaginez, JPEG a plus de versions! Et en plus, c'est du JPEG progressif? Ceci est un drapeau important. Il explique comment vos blocs seront distribués plus loin.

Si JPEG n'est pas progressif, de quoi avez-vous besoin pour décoder vos blocs? Qualité JPEG, cette même plaque. L'assiette dans laquelle vous divisez vos blocs est de qualité. Mais JPEG a deux qualités. La première qualité est responsable du canal Y, la seconde - pour les canaux CB et CR, c'est ce qui détermine la couleur. Étant donné que nous avons mis la qualité dans un fichier et que nous avons tout compressé avec un algorithme de compression sans perte, nous avons toujours besoin d'un dictionnaire Huffman Tables spécial pour développer cela.

Viennent ensuite vos blocs, puis votre JPEG est terminé.



D'accord, une histoire progressive. Tout est exactement pareil. Au tout début, vous avez un méta-morceau. Vient ensuite votre qualité sous la forme de 64 numéros, plus 64 numéros. Et puis juste les mêmes blocs, mais juste un peu différents avec des nombres distribués. Première partie des blocs, puis une autre partie, une autre partie et ainsi de suite. Lorsque vous recevez ces blocs, le navigateur dessine une approximation de votre JPEG, car, en fait, ces chiffres sont une approximation de votre fichier.



À propos de JPEG, nous avons terminé, vous pouvez expirer, tout va bien. Parlons d'une chose aussi intéressante que JPEG 2000. L'un de vous en production utilise-t-il JPEG 2000? D'accord, qui a déjà entendu parler de ça? Et lequel d'entre vous a lu dans Lighthouse - «utiliser des formats modernes»?

En général, JPEG 2000 est un format intéressant intéressant, qui, premièrement, est plus efficace que JPEG. Deuxièmement, vous ne le croirez pas, dans certains cas, il est plus efficace que WebP, dont nous parlerons plus tard.

Il sait être transparent, sait compresser sans perte. Juste le format parfait. Mais malheureusement, oui, cela ne fonctionne que dans Safari.

Il convient de mentionner que JPEG 2000 est conçu de manière très complexe et fonctionne sur des mathématiques intéressantes appelées transformée en ondelettes. Si vous êtes soudainement intéressé, google, et nous irons plus loin.



Ensuite, nous devons soudainement parler de la vidéo. L'ensemble de ce rapport concerne l'optimisation d'image et les images. Mais la vidéo ici est très importante, vous verrez pourquoi maintenant. Quand on pense à une vidéo, le premier mot qui nous vient à l'esprit est «codec». La vidéo doit être encodée d'une manière ou d'une autre, et pour montrer la vidéo, nous devons la décoder. Si nous décodons le flux vidéo, qu'obtenons-nous?

Tout d'abord, nous avons un ensemble de cadres. Mais ne pensez pas à ces cadres comme des images dans le GIF. Tout faux. Quelles trames dépendent beaucoup du codec. Mais dans le cas général, vous pouvez supposer que vous avez une image clé. Vous pouvez retirer un chat de l’image clé - en ce sens, toute image qui se trouve sur cette image clé. Et il y a des cadres dépendants. Il est impossible de faire sortir un chat du cadre dépendant, car le cadre dépendant stocke non seulement des informations non pas sur l'image, le cas échéant, mais sur la façon dont les blocs du cadre précédent ou précédent se sont déplacés. Par conséquent, vous ne pouvez pas obtenir d'image pour une image dépendante avant d'avoir décodé un peu.

Tout ce dont nous allons parler maintenant, c'est de la compression des images clés et intra-images. Voici comment compresser une image à l'intérieur d'une image clé.

Regardons un codec abstrait dans le vide et comparons-le avec JPEG. Jusqu'à présent, il semble - pourquoi faire cela? Tout deviendra plus clair, croyez-moi.



Encore une fois, nous répétons la même chose que nous faisons avec JPEG,. Vous prenez une photo, la divisez en canaux, effectuez un sous-échantillonnage en canaux. Même histoire ici. Ensuite, vous divisez cette image en blocs. Mais il existe déjà des fonctionnalités. Tout d'abord, la taille du bloc dans lequel vous pénétrez dépend de votre codec. Et ces blocs peuvent être très grands. Pour JPEG - 8 par 8. Pour les codecs vidéo - il peut être, par exemple, 128 par 128.

Plus loin. Si vous obtenez de très petits détails sur votre image auxquels vous souhaitez prêter attention, vous pouvez toujours subdiviser les blocs un peu, environ à la taille 4 par 4. Comment vous cassez les blocs, cet algorithme de partitionnement dépend du codec.

Et le plus récent - la taille maximale des blocs, encore une fois, est spécifique à votre codec. Un codeur fait partie du codec, à comprendre en terminologie. Ici, nous sommes toujours similaires au JPEG.



Ce qui ne ressemble pas au JPEG, c'est le codage prédictif. Nous avons parlé de lui en partie de peengeshki. La compression vidéo intraframe est tellement cool et efficace à cause de cela. Que se passe t-il ici?

Nous essayons de prédire les pixels de chaque bloc en fonction des précédents. Autrement dit, nous ne stockons pas les pixels sous forme brute, nous les prédisons. Les options de prédiction sont nombreuses. Dans un codec, nous pouvons utiliser différentes variantes de prédictions. De plus, pour toutes sortes de codecs complexes de ces options, jusqu'à 35, par exemple. Comment pouvez-vous faire cela. Regardons un exemple.

Ici, vous avez le bloc. Vous dites: je veux y prédire des pixels. Vous regardez vers la gauche, vous regardez vers le haut et vous vous souvenez de ce qui reste et du dessus. Ensuite, vous prenez toutes les valeurs de pixels que vous avez trouvées, faites la moyenne et remplissez-la avec un bloc, et dites: J'ai prédit. Si vous avez deviné à droite, et au fait, sur la petite image où il y a des flèches bleues, vous avez deviné à droite, alors vous êtes génial, vous n'avez rien d'autre à faire. Mais, si vous ne l'avez pas deviné, vous devez enregistrer la différence entre ce qui est réellement et ce que vous avez prédit. Cette différence se comprime beaucoup, beaucoup mieux que la valeur du pixel pur.



Ensuite, tout est exactement le même qu'en JPEG. Vous transformerez le bloc résultant. Mais la particularité de toutes sortes de codecs différents est que vous pouvez utiliser non pas DCT (transformée en cosinus discrète), mais autre chose. Ce qu'il faut utiliser dépend du codec.



Puis à nouveau les mêmes plaques, mais contrairement au JPEG, vous pouvez utiliser plusieurs plaques pour l'ensemble de votre fichier, et vous pouvez utiliser plusieurs plaques différentes pour différents blocs. Imaginez - vous avez une personne, par exemple, contre le ciel. Peut-être, puisque le ciel est bleu, vous n'avez pas besoin d'une qualité spéciale là-bas, vous pouvez utiliser une qualité pour le ciel, une plaque. Et pour une personne qui a une texture, des vêtements, utilisez une qualité différente, et cela se révèle cool et efficace.



Le plus récent est ce que JPEG ne possède pas et ce qui fait très, très peu défaut. C'est l'utilisation de filtres. Lorsque nous avons tous récolté, nous obtenons de tels artefacts désagréables après la compression. Si vous avez déjà compressé des JPEG en mauvaise qualité, vous devriez voir comment les JPEG se désagrègent simplement en blocs terribles cauchemardesques. En général, pour se débarrasser de ces artefacts, les codecs vidéo utilisent une chose spéciale. Ils appliquent des filtres et les bords de ces blocs se lissent. La technologie des anciens, qui nous permettait de faire de même avec JPEG, était telle. Vous prenez votre JPEG, le compressez très, très fort, puis le pliez comme ceci pour que rien ne soit visible. En général, c'est à peu près la même chose, mais cela a déjà été fait au niveau du codec. Génial.



Naturellement, lorsque nous avons essayé et que tout était terminé, nous devons maintenant compresser les blocs reçus sans perte. Nous avons serré, bien fait. L'algorithme de compression est similaire à JPEG, mais toujours différent. Ici, il faut comprendre que la compression sans perte est limitée par la limite naturelle. Nous voulons vraiment nous en approcher, et la meilleure façon de s'en rapprocher est d'utiliser un algorithme appelé codage arithmétique. Et il y a aussi toutes sortes de variations. Cela dépend à nouveau de l'encodeur, mais supposons simplement qu'il existe une compression sans perte et env.



J'ai longtemps voulu appeler ces codecs abstraits dans le vide par leurs noms propres. Une petite excursion historique. Que s'est-il passé en 20 ans? Je ne parle que des codecs vidéo qui sont au moins en quelque sorte pris en charge sur le Web. H.264 est un codec qui prend en charge tout et tout le monde. Il s'agit de la solution par défaut pour toute la vidéo. Après un certain temps, après quelques années, le codec vidéo VP8 apparaît.

Ici commencent des guerres sauvages, des holivars sur le sujet, lesquels de ces codecs sont les meilleurs. J'ai googlé pendant très longtemps - il n'y a pas de réponse. De grands articles scientifiques ont été écrits à ce sujet, mais en moyenne, si je dis la même chose maintenant, une tomate volera en moi. Mais bon, ce sont les mêmes. Moyenne. Alors pourquoi avons-nous besoin d'une seconde?

Le second est nécessaire car il est gratuit. Si vous utilisez H.264, vous devez transporter de l'argent MPEG dans certaines circonstances. Pour VP8, vous n'avez pas besoin de transporter d'argent. C'est bon. Donc, image clé VP8 - c'est WebP. En effet, pourquoi devrions-nous inventer un nouveau format d'image? Nous prenons l'image clé, nous avons essayé si fort, nous avons tout serré. Nous appelons tout cela un nouveau format d'images, et le tour est joué!

Que se passe-t-il ensuite? Puis après un certain nombre d'années, deux codecs vidéo plus sympas, de MPEG et de Google, apparaissent presque simultanément. De Google - VP9, ​​de MPEG - H.265. À côté de H.265, il existe une nouvelle norme d'image appelée HEIF. Il n'est pas pris en charge par les navigateurs, pas du tout. Mais il est pris en charge par vos appareils Apple. La norme HEIF est incroyablement intéressante, car ce n'est qu'une abstraction de cette idée. Dans un conteneur HEIF, vous pouvez créer une image clé à partir de presque n'importe quel codec. Autrement dit, VP8 n'est pas un format moderne. Mais HEIF est moderne.

Que se passe-t-il ensuite? Maintenant dans une très grande organisation, qui comprend Mozilla et Google, un codec vidéo appelé AV1 est en cours de sciage. L'organisation s'appelle Alliance for Open Media. La qualité de la vidéo AV1 est plusieurs fois supérieure à tout ce qui était auparavant. Il est libre, il est libre de droits, il est très cool. Nous avons un si beau conteneur HEIF. Il ne nous reste plus qu'à y insérer l'image clé AV1. Et c'est fait. Le nouveau format pour pousser l'image clé AV1 dans un conteneur HEIF s'appelle AVIF. C'est ce qui nous attend à l'avenir. Peut-être qu'un jour nous l'utiliserons nativement.

Mais nous pouvons l'utiliser maintenant. Nous venons de mettre une image de la vidéo sur la page et de dire: voila, vous avez une photo.



Comment cela se fait-il dans webp? WebP est, comme je l'ai dit, une image clé VP8 emballée dans un conteneur appelé riff. Il y a un tel en-tête dans le conteneur riff. Là, ne le croyez pas, il est écrit que c'est WebP. Qui en douterait. PNG dit que c'est PNG WebP, et le voilà.

Mais WebP a une fonctionnalité intéressante: l'image clé VP8 peut se trouver à l'intérieur, et c'est ce qu'on appelle généralement WebP. Mais l'image clé VP8 ne l'est peut-être pas. En général, WebP prend en charge la compression sans perte. WebP lossless est un format complètement différent qui n'a rien à voir avec VP8, compression avec perte, etc. Par conséquent, lorsque quelqu'un vous dit que WebP est plus efficace qu'autre chose, la première question à se poser est de savoir WebP quelque chose? Parce que si nous parlons de compression sans perte, il y a une allée naturelle à laquelle nous pouvons nous efforcer. Ces différences, "60% plus efficaces que ...", ne sont probablement pas sans perte, mais WebP avec pertes.

D'accord, assez de théorie, j'en ai marre, regardons déjà quelque chose. Cliquable




Commençons par ça. Nous prenons une photo prise par un appareil photo professionnel. Découpez-en un morceau de 1000 par 1000 pixels. Incidemment, cela semble très cool sur le projecteur. Nous commençons à considérer de petits détails. Dans le même temps, nous compressons cette pièce pour obtenir exactement 15 kilo-octets. Clickable Voir ce qui se passe. JPEG est tombé en blocs immédiatement. En effet, de faible qualité, on s'y attendait. Voici à quoi ressemble WebP. Il est également tombé en blocs, mais ces blocs ne sont pas si clairement visibles. Lorsque vous utilisez l'encodeur WebP et le contrôlez avec vos mains, vous pouvez contrôler la puissance du filtre utilisé dans WebP. Et si vous dévissez ce filtre plus fort, vous pouvez vous débarrasser d'un grand nombre d'artefacts de bloc. Par conséquent, purement théoriquement, ces blocs peuvent également être supprimés.








Et voici AV1. Admirons simplement en silence. Regardez comme il est cool. AV1 est pris en charge dans Firefox, dans Chrome, vous pouvez donc utiliser la vidéo AV1 au lieu d'une image si vous le souhaitez. Clickable Il y a un spoiler, en vain je l'ai ajouté. La situation lorsque PNG bat WebP. Oui, PNG dans ce cas est plus efficace que WebP. C'est parce que j'ai utilisé WebP avec perte. Clickable Qu'est-ce que j'ai fait avec la peengeshka? J'ai fait le mode de couleur indexé, c'est-à-dire que j'ai coupé la palette, à mon avis, à 16 couleurs. C'est assez efficace pour une photo en noir et blanc. Ça s'est bien passé, ça s'est beaucoup contracté. Pour le WebP avec perte de qualité, nous avons obtenu une taille plus grande. Cependant, pour sans perte, cela est prévu, il est plus efficace que peengeshka. Nous avons gagné.











Je résume. Les pangshes encastrés très cool peuvent vaincre les formats de compression avec perte et ne pas vaincre WebP sans perte. Malheureusement, malheureusement. Clickable Peut-être êtes-vous tourmenté par la question: pourquoi faites-vous cela, savons-nous ce qu'est le SVG? Et je sais, mais pour certaines tailles, le PNG est plus efficace. Cette image s'avère plus efficace que SVG pour des tailles comme 200 par 200. Ensuite, SVG, bien sûr, gagne. Cliquable Maintenant, regardons Mike. Voici Mike. Ses dimensions sont de 3000 par 3000 pixels. JPEG vs WebP. Il était évident ici que JPEG gagnait. Mais dans ce cas, j'ai obtenu environ six pour cent de victoire pour à peu près la même qualité visuelle. Ceci est une caractéristique de la photo et comment j'ai préparé cette photo. Vous pouvez alors me demander comment je l'ai fait.












Cliquable

, mais tout dépend beaucoup des paramètres de l'encodeur. Si vous essayez très fort et dévissez les paramètres de l'encodeur d'une manière spéciale, alors JPEG commencera à vaincre WebP en taille pour la même qualité visuelle. Je voudrais conclure que les chats rétrécissent mieux que JPEG, mais non. Ceci est juste un exemple de la façon dont vous pouvez le dévisser comme vous le souhaitez si vous le souhaitez. Cliquable Il s'agit d'une qualité très faible. JPEG tombe en blocs. Cela est particulièrement évident à droite sur le projecteur - le nez est devenu bleu chez le chien, il est devenu carré. WebP n'est pas si malade. Tout semble être cool et bon, mais le fait est que pour des qualités très, très faibles, WebP donne environ deux, voire trois fois la taille du fichier que JPEG. Ici, vous devez également réfléchir à la qualité que vous souhaitez. Cliquable









C'est la comparaison la plus honnête. Il faut donc comparer, car H.264 et WebP sont similaires. Selon vous, qui a gagné ici? H.264. Mais pour être honnête, l'expérience n'était pas entièrement propre. Dans le bon sens, à la fois dans WebP et dans H.264, la trame vidéo est à peu près sans ambiguïté. Cliquable Mais avec AV1, tout est absolument clair. Trente pour cent gagnent sur la même qualité visuelle. Hourra! Cliquable Il est très important de comprendre quel type d'image vous mettez et comment tel ou tel format répond à la qualité de l'image. Ici, le chien au format WebP pèse 79 kilo-octets en qualité, soit environ 75% contre 56 kilo-octets en JPEG. Pourquoi cela arrive-t-il?











Parce que pas un seul codec vidéo, pas un seul format ne peut compresser correctement le bruit. Si votre image présente de telles distorsions, points et autres choses, il est fort probable que vous ayez des problèmes de compression. Si vous pouvez prendre une autre photo et supprimer ce bruit, supprimez-le.

Donc, les images sont une chose compliquée. Peuvent-ils ralentir votre interface? Une question importante et bonne.



Réponse: probablement pas. Pourquoi ça arrive? Parce que lorsque l'image est décodée, elle se produit dans un flux séparé. Mais il y a une exception - si vous dessinez quelque chose sur un canevas, vous devez vous rappeler que le décodage d'image se produira dans le flux principal et que les boutons ne peuvent pas être pressés à ce moment.



Si vous voulez vraiment en faire une affaire, ouvrez Chrome, recherchez les threads de pixellisation correspondants et l'événement Image Decode, vous le trouverez.



Si vous êtes très, très curieux, vous pouvez aller dans l'onglet de traçage et y voir avec des détails ce qui se passe lors du décodage d'une image.

Outils d'optimisation


La chose la plus importante est les outils d'optimisation. Nous savons maintenant à peu près ce que nous voulons. Reste à comprendre comment nous procédons.



L'outil d'optimisation d'image le plus important est le concepteur, aussi étrange que cela puisse paraître. Seule cette merveilleuse personne sait quel problème vous voulez résoudre avec lui. Nous n'ajoutons pas d'images aux pages afin de les optimiser au frais, mais pour impressionner les utilisateurs. Pour maintenir un équilibre entre le degré d'optimisation et l'expérience utilisateur, utilisez un concepteur qui aide beaucoup.


Lien de la diapositive Le

deuxième outil est notre open source martien, dont j'ai promis de parler. Cette chose s'appelle imgproxy et résout tous nos problèmes en général. Sur mes projets, j'utilise uniquement imgproxy, cette chose peut faire presque tout ce que je veux.



Comment ça fonctionne? Avez-vous un souhait pour la photo. Vous voulez une image d'une certaine taille avec une certaine optimisation. Et quelque part loin, vous avez une image de toute résolution - peut-être sur l'ordinateur local, ou peut-être quelque part chez l'utilisateur ou en général n'importe où. Il vous suffit de créer une URL spéciale et de demander à imgproxy de redimensionner votre image. Il s'agit d'un tel service, il peut être dans le cloud ou ailleurs. Autrement dit, vous aviez un énorme chat, vous envoyez une URL spéciale à imgproxy. Il fait tout ce que vous voulez à la volée.



Si cela ne semble pas clair, voyons à quoi ressemble la demande d'imgproxy. Tout d'abord, vous devez indiquer où se trouve imgproxy. Deuxièmement, si vous ne voulez pas être aspiré de manière agressive, l'URL que vous demandez serait bien de signer numériquement. Vous ne pouvez pas faire cela, c'est juste une mesure de protection supplémentaire.

De plus, si vous souhaitez redimensionner, passez directement dans l'url les paramètres de redimensionnement. Si vous voulez optimiser - la même chose. Il vous suffit de transférer l'adresse d'origine de votre photo.



Si vous souhaitez des optimisations manuelles, il existe un vaste ensemble d'outils. Je ne vais pas tous les décrire maintenant. Le matériel du rapport, que je vous enverrai, a tout.



Voici le plus cool et utile. Ces toutes les images ne sont pas si compliquées. Je pense que j'ai réussi à vous le transmettre. Si vous êtes intéressé, prenez votre langage de programmation préféré - probablement JavaScript, bien que loin d'être un fait - et commencez à tout régler.

Si vous souhaitez le faire dans un navigateur, veuillez. Vous avez probablement besoin d'une liaison qui est probablement écrite en plus ou en C. Mais qu'est-ce qui vous empêche de tout compiler dans WebAssembly? Il y a une application sympa appelée Squoosh. C'est exactement cela. Vous aussi, essayez, ce sera cool. J'aime vraiment.

Merci à tous pour votre attention. Documents pour le rapport - par référence .

All Articles