Parfois, j'ai besoin d'écrire plus de documentation que de simples commentaires dans le code. Et parfois, ces explications ont besoin de captures d'écran. Parfois, les conditions pour obtenir une telle capture d'écran sont si étranges que je demande à un développeur de prendre une capture d'écran pour moi. Parfois, la capture d’écran ne correspond pas à mes spécifications et je dois la redimensionner pour qu’elle ait une belle apparence.
Comme vous pouvez le constater, les circonstances justifiant le besoin de la magie "Lossless Screenshot Resizer" sont très improbables. Quoi qu'il en soit, il me semble que j'en ai besoin tous les jours. Mais ça n'existe pas encore.
Je t'ai déjà vu sur PCG résoudre des énigmes graphiques impressionnantes auparavant, alors je suppose que celui-ci est plutôt ennuyeux pour toi ...
spécification
- Le programme prend une capture d'écran d'une seule fenêtre en tant qu'entrée
- La capture d'écran ne fait pas appel à des effets de verre ou similaires (vous n'avez donc pas besoin de vous occuper des éléments d'arrière-plan qui transparaissent)
- Le format de fichier en entrée est PNG (ou tout autre format sans perte afin que vous n'ayez pas à traiter d'artefacts de compression).
- Le format du fichier de sortie est le même que celui du fichier d'entrée
- Le programme crée une capture d'écran de taille différente en sortie. La taille minimale requise est réduite.
- L'utilisateur doit spécifier la taille de sortie attendue. Si vous pouvez donner des indications sur la taille minimale que votre programme peut produire à partir d'une entrée donnée, c'est utile.
- La capture d'écran de sortie ne doit pas contenir moins d'informations si interprétée par un humain. Vous ne devez pas supprimer le texte ou le contenu de l'image, mais vous devez supprimer les zones avec uniquement un arrière-plan. Voir les exemples ci-dessous.
- S'il n'est pas possible d'obtenir la taille attendue, le programme doit l'indiquer et non pas simplement bloquer ou supprimer des informations sans préavis.
- Si le programme indique les zones qui seront supprimées pour des raisons de vérification, sa popularité augmentera.
- Le programme peut nécessiter une autre saisie de l'utilisateur, par exemple pour identifier le point de départ de l'optimisation.
Règles
C'est un concours de popularité. La réponse avec le plus de votes le 08/03/2015 est acceptée.
Exemples
Capture d'écran de Windows XP. Taille originale: 1003x685 pixels.
Exemple de zones (rouge: vertical, jaune: horizontal) pouvant être supprimées sans perte d’informations (texte ou images). Notez que la barre rouge n'est pas contiguë. Cet exemple n'indique pas tous les pixels possibles pouvant éventuellement être supprimés.
Redimensionné sans perte: 783x424 pixels.
Windows 10 capture d'écran. Taille originale: 999x593 pixels.
Exemple de zones pouvant être supprimées.
Capture d'écran redimensionnée sans perte: 689x320 pixels.
Notez que le texte du titre ("Téléchargements") et "Ce dossier est vide" ne sont plus centrés. Bien sûr, il serait plus judicieux qu’il soit centré et si votre solution le permet, elle devrait devenir plus populaire.
la source
Réponses:
Python
la fonction
delrows
supprime toutes les lignes dupliquées sauf une et renvoie l'image transposée. En l'appliquant deux fois, les colonnes sont également supprimées et transposées. De plus,threshold
contrôle le nombre de pixels pouvant différer pour que deux lignes soient toujours considérées comme identiques.En retournant le comparateur
mask
de>
à, vous<=
obtiendrez les zones supprimées, qui sont généralement des espaces vierges.joué au golf (parce que pourquoi pas)
Au lieu de comparer chaque pixel, il ne regarde que la somme. Cet effet secondaire convertit également la capture d'écran en niveaux de gris et ne permet pas de conserver les permutations de la somme, comme la flèche vers le bas dans la barre d'adresse du Win8. capture d'écran
la source
Java: essayez sans perte et faites appel au contenu
(Meilleur résultat sans perte jusqu'à présent!)
Lorsque j’ai examiné cette question pour la première fois, j’ai pensé que ce n’était pas un casse-tête ou un défi, mais bien une personne qui avait désespérément besoin d’un programme et de son code;) Mais c’est dans ma nature de résoudre des problèmes de vision afin que je ne puisse m'empêcher d’essayer ce défi !
Je suis venu avec l'approche suivante et la combinaison d'algorithmes.
En pseudo-code, cela ressemble à ceci:
Techniques utilisées:
Le programme
Le programme peut recadrer des captures d'écran sans perte, mais dispose d'une option permettant de recadrer un recadrage en fonction du contenu, qui n'est pas sans perte à 100%. Les arguments du programme peuvent être peaufinés pour obtenir de meilleurs résultats.
Remarque: le programme peut être amélioré de nombreuses manières (je n'ai pas beaucoup de temps libre!)
Arguments
Code
Résultats
Capture d'écran XP sans perte sans la taille souhaitée (compression maximale sans perte)
Arguments: "image.png" 1 1 5 10 false 0
Résultat: 836 x 323
XP capture d'écran à 800x600
Arguments: "image.png" 800 600 6 10 true 60
Résultat: 800 x 600
L'algorithme sans perte supprime environ 155 lignes horizontales et ne prend plus en compte le contenu, ce qui permet de voir certains artefacts.
Windows 10 capture d'écran à 700x300
Arguments: "image.png" 700 300 6 10 true 60
Résultat: 700 x 300
L'algorithme sans perte supprime 270 lignes horizontales, puis retombe en suppression basée sur le contenu, ce qui en supprime 29 autres. Verticalement, seul l'algorithme sans perte est utilisé.
Capture d'écran compatible avec le contenu de Windows 10 à 400x200 (test)
Arguments: "image.png" 400 200 5 10 true 600
Résultat: 400 x 200
Il s'agissait d'un test permettant de voir à quoi ressemblerait l'image résultante après une utilisation intensive de la fonctionnalité prenant en compte le contenu. Le résultat est lourdement endommagé mais pas méconnaissable.
la source
C #, algorithme comme je le ferais manuellement
C’est mon premier programme de traitement d’image et il a fallu un certain temps pour le mettre en oeuvre
LockBits
, etc. Mais je voulais que ce soit rapide (avecParallel.For
) pour obtenir un retour presque instantané.Fondamentalement, mon algorithme est basé sur des observations sur la façon dont je supprime manuellement les pixels d'une capture d'écran:
Pour le moment je le fais horizontalement seulement. Le résultat vertical peut utiliser le même algorithme et fonctionner sur une image tournée de 90 °, donc en théorie, c'est possible.
Résultats
Voici une capture d'écran de mon application avec les régions détectées:
Et voici le résultat pour la capture d'écran de Windows 10 et le seuil de 48 pixels. La sortie mesure 681 pixels de large. Malheureusement, ce n'est pas parfait (voir "Recherche de téléchargements" et quelques barres de colonnes verticales).
Et un autre avec un seuil de 64 pixels (567 pixels de large). Cela a l'air encore mieux.
Résultat global en appliquant la rotation à la culture de tous les fonds (567x304 pixels).
Pour Windows XP, je devais changer un peu le code car les pixels ne sont pas exactement égaux. J'applique un seuil de similarité de 8 (différence de la valeur RVB). Notez quelques artefacts dans les colonnes.
Code
Eh bien, ma première tentative de traitement d’image. Ne semble pas très bien, n'est-ce pas? Cela ne fait que lister l'algorithme principal, pas l'interface utilisateur et pas la rotation à 90 °.
la source
Haskell, en utilisant la suppression naïve de lignes séquentielles en double
Malheureusement, ce module ne fournit qu'une fonction de type très générique
Eq a => [[a]] -> [[a]]
, car je ne sais pas comment éditer des fichiers image dans Haskell. Cependant, je suis certain qu'il est possible de transformer une image PNG en une[[Color]]
valeur et j'imagineinstance Eq Color
que facilement définissable.La fonction en question est
resizeL
.Code:
Explication:
Remarque:
a : b
signifie un élémenta
préfixé à la liste de typesa
, résultant en une liste. C'est la construction fondamentale des listes.[]
dénote la liste vide.Note: le
a :: b
moyena
est de typeb
. Par exemple, sia :: k
, alors(a : []) :: [k]
, où[x]
indique une liste contenant des objets de typex
.Cela signifie que
(:)
lui - même, sans aucun argument,:: a -> [a] -> [a]
. Le->
dénote une fonction de quelque chose à quelque chose.Ils
import Data.List
obtiennent simplement du travail que d'autres personnes ont fait pour nous et nous permettent d'utiliser leurs fonctions sans les réécrire.Tout d'abord, définissez une fonction
nubSequential :: Eq a => [a] -> [a]
.Cette fonction supprime les éléments suivants d'une liste identiques.
Ainsi,
nubSequential [1, 2, 2, 3] === [1, 2, 3]
. Nous allons maintenant abréger cette fonction ennS
.Si
nS
est appliqué à une liste vide, rien ne peut être fait, et nous retournons simplement une liste vide.Si
nS
est appliqué à une liste avec un contenu, le traitement réel peut être effectué. Pour cela, nous avons besoin d’une deuxième fonction, ici dans unewhere
clause, pour utiliser la récursivité, car notrenS
ne garde pas la trace d’un élément à comparer.Nous nommons cette fonction
g
. Cela fonctionne en comparant son premier argument à la tête de la liste qui lui a été donnée, et en écartant la tête si elles correspondent, et en s'appelant à la queue avec l'ancien premier argument. Si ce n'est pas le cas, il ajoute la tête sur la queue et passe à travers lui-même avec la tête comme premier argument.Pour l'utiliser
g
, nous lui donnons la tête de l'argument denS
et la queue comme ses deux arguments.nS
est maintenant de typeEq a => [a] -> [a]
, prenant une liste et retournant une liste. Cela nécessite que nous puissions vérifier l’égalité entre les éléments, comme cela est fait dans la définition de la fonction.Ensuite, nous composons les fonctions
nS
et entranspose
utilisant l'(.)
opérateur.Fonctions de composition signifie ce qui suit:
(f . g) x = f (g (x))
.Dans notre exemple,
transpose
fait pivoter un tableau de 90 °,nS
supprime tous les éléments séquentiels égaux de la liste, dans ce cas d’autres listes (c’est ce qu’est un tableau), letranspose
fait pivoter en arrière etnS
supprime à nouveau les éléments égaux séquentiels. Cela consiste essentiellement à supprimer les lignes et colonnes en double suivantes.Ceci est possible car si
a
est vérifiable pour l'égalité (instance Eq a
), alors l'[a]
est aussi.En bref:
instance Eq a => Eq [a]
la source