A veces necesito escribir más documentación que solo comentarios en el código. Y a veces, esas explicaciones necesitan capturas de pantalla. A veces, las condiciones para obtener una captura de pantalla son tan extrañas que le pido a un desarrollador que me tome una captura de pantalla. A veces, la captura de pantalla no se ajusta a mis especificaciones y tengo que cambiar su tamaño para que se vea bien.
Como puede ver, las circunstancias para la necesidad del mágico "Ressless Screenshot Resizer" son muy poco probables. De todos modos, para mí parece que lo necesito todos los días. Pero aún no existe.
Te he visto aquí en PCG resolver asombrosos rompecabezas gráficos antes, así que supongo que este es bastante aburrido para ti ...
Especificación
- El programa toma una captura de pantalla de una sola ventana como entrada
- La captura de pantalla no utiliza efectos de vidrio o similares (por lo que no necesita lidiar con ningún material de fondo que brille)
- El formato del archivo de entrada es PNG (o cualquier otro formato sin pérdidas para que no tenga que lidiar con artefactos de compresión)
- El formato del archivo de salida es el mismo que el formato del archivo de entrada.
- El programa crea una captura de pantalla de diferente tamaño como salida. El requisito mínimo se está reduciendo de tamaño.
- El usuario deberá especificar el tamaño de salida esperado. Si puede dar pistas sobre el tamaño mínimo que su programa puede producir a partir de la entrada dada, eso es útil.
- La captura de pantalla de salida no debe tener menos información si es interpretada por un humano. No eliminará el contenido de texto o imagen, pero eliminará áreas con fondo solamente. Ver ejemplos a continuación.
- Si no es posible obtener el tamaño esperado, el programa debe indicar eso y no simplemente bloquear o eliminar información sin previo aviso.
- Si el programa indica las áreas que se eliminarán por razones de verificación, eso debería aumentar su popularidad.
- El programa puede necesitar alguna otra entrada del usuario, por ejemplo, para identificar el punto de partida para la optimización.
Reglas
Este es un concurso de popularidad. Se acepta la respuesta con más votos el 2015-03-08.
Ejemplos
Captura de pantalla de Windows XP. Tamaño original: 1003x685 píxeles.
Áreas de ejemplo (rojo: vertical, amarillo: horizontal) que se pueden eliminar sin perder ninguna información (texto o imágenes). Tenga en cuenta que la barra roja no es contigua. Este ejemplo no indica todos los píxeles posibles que podrían eliminarse potencialmente.
Se redimensionó sin pérdidas: 783x424 píxeles.
Captura de pantalla de Windows 10. Tamaño original: 999x593 píxeles.
Áreas de ejemplo que se pueden eliminar.
Captura de pantalla redimensionada sin pérdidas: 689x320 píxeles.
Tenga en cuenta que está bien que el texto del título ("Descargas") y "Esta carpeta esté vacía" ya no estén centrados. Por supuesto, sería mejor si estuviera centrado, y si su solución lo proporciona, debería ser más popular.
fuente
Respuestas:
Pitón
la función
delrows
elimina todas las filas duplicadas menos una y devuelve la imagen transpuesta, al aplicarla dos veces también elimina las columnas y la transpone nuevamente. Ademásthreshold
controla cuántos píxeles pueden diferir para que dos líneas sigan siendo consideradas igualesAl voltear el comparador
mask
desde>
a, se<=
generarán las áreas eliminadas, que en su mayoría son espacios en blanco.golfed (porque por qué no)
En lugar de comparar cada píxel, solo mira la suma, como efecto secundario esto también convierte la captura de pantalla en escala de grises y tiene problemas con permutaciones de preservación de la suma, como la flecha hacia abajo en la barra de direcciones del Win8 captura de pantalla
fuente
Java: intente sin pérdidas y recurra a contenido
(¡El mejor resultado sin pérdidas hasta ahora!)
Cuando examiné por primera vez esta pregunta, pensé que no era un rompecabezas o un desafío, solo alguien que necesitaba desesperadamente un programa y su código;) Pero está en mi naturaleza resolver problemas de visión, por lo que no pude evitar que este intentara este desafío. !
Se me ocurrió el siguiente enfoque y combinación de algoritmos.
En pseudocódigo se ve así:
Técnicas utilizadas
El programa
El programa puede recortar capturas de pantalla sin pérdidas, pero tiene una opción para recurrir a recortes conscientes del contenido que no son 100% sin pérdidas. Los argumentos del programa se pueden ajustar para lograr mejores resultados.
Nota: El programa se puede mejorar de muchas maneras (¡no tengo tanto tiempo libre!)
Argumentos
Código
Resultados
Captura de pantalla XP sin pérdida sin el tamaño deseado (compresión máxima sin pérdida)
Argumentos: "image.png" 1 1 5 10 falso 0
Resultado: 836 x 323
Captura de pantalla de XP a 800x600
Argumentos: "image.png" 800600 6 10 verdadero 60
Resultado: 800 x 600
El algoritmo sin pérdida elimina alrededor de 155 líneas horizontales de las que el algoritmo recurre a la eliminación consciente del contenido para que se puedan ver algunos artefactos.
Captura de pantalla de Windows 10 a 700x300
Argumentos: "image.png" 700300 6 10 verdadero 60
Resultado: 700 x 300
El algoritmo sin pérdida elimina 270 líneas horizontales de las que el algoritmo recurre a la eliminación de contenido que elimina otras 29. Vertical solo se utiliza el algoritmo sin pérdida.
Captura de pantalla de Windows 10 con reconocimiento de contenido a 400x200 (prueba)
Argumentos: "image.png" 400200 5 10 verdadero 600
Resultado: 400 x 200
Esta fue una prueba para ver cómo se vería la imagen resultante después del uso severo de la función de contenido. El resultado está muy dañado pero no es irreconocible.
fuente
C #, algoritmo como lo haría manualmente
Este es mi primer programa de procesamiento de imágenes y me llevó un tiempo implementarlo con todo eso,
LockBits
etc. Pero quería que fuera rápido (usandoParallel.For
) para obtener una respuesta casi instantánea.Básicamente, mi algoritmo se basa en observaciones sobre cómo elimino píxeles manualmente de una captura de pantalla:
Por el momento lo hago solo horizontalmente. El resultado vertical puede usar el mismo algoritmo y operar en una imagen girada a 90 °, por lo que en teoría es posible.
Resultados
Esta es una captura de pantalla de mi aplicación con regiones detectadas:
Y este es el resultado de la captura de pantalla de Windows 10 y el umbral de 48 píxeles. La salida tiene 681 píxeles de ancho. Lamentablemente, no es perfecto (consulte "Buscar descargas" y algunas de las barras de columnas verticales).
Y otro con umbral de 64 píxeles (567 píxeles de ancho). Esto se ve aún mejor.
Resultado general aplicando rotación para recortar también desde abajo (567x304 píxeles).
Para Windows XP, necesitaba cambiar un poco el código ya que los píxeles no son exactamente iguales. Estoy aplicando un umbral de similitud de 8 (diferencia en el valor RGB). Tenga en cuenta algunos artefactos en las columnas.
Código
Bueno, mi primer intento de procesamiento de imágenes. No se ve muy bien, ¿verdad? Esto solo enumera el algoritmo central, no la interfaz de usuario y no la rotación de 90 °.
fuente
Haskell, utilizando la eliminación ingenua de líneas secuenciales duplicadas
Desafortunadamente, este módulo solo proporciona una función con un tipo muy genérico
Eq a => [[a]] -> [[a]]
, ya que no tengo idea de cómo editar archivos de imagen en Haskell, sin embargo, estoy seguro de que es posible transformar una imagen PNG a un[[Color]]
valor y me imaginoinstance Eq Color
que sería Fácilmente definible.La función en cuestión es
resizeL
.Código:
Explicación:
Nota:
a : b
significa elementoa
prefijado a la lista de tipo dea
, lo que resulta en una lista. Esta es la construcción fundamental de las listas.[]
denota la lista vacía.Nota:
a :: b
significaa
es de tipob
. Por ejemplo, sia :: k
, entonces(a : []) :: [k]
, donde[x]
denota una lista que contiene cosas de tipox
.Esto significa que
(:)
sí mismo, sin ningún argumento,:: a -> [a] -> [a]
. El->
denota una función de algo a algo.El
import Data.List
simplemente consigue un trabajo a otras personas hicieron por nosotros y nos permite utilizar sus funciones sin tener que reescribir ellos.Primero, defina una función
nubSequential :: Eq a => [a] -> [a]
.Esta función elimina elementos posteriores de una lista que son idénticos.
Por lo tanto,
nubSequential [1, 2, 2, 3] === [1, 2, 3]
. Ahora abreviaremos esta función comonS
.Si
nS
se aplica a una lista vacía, no se puede hacer nada, y simplemente devolvemos una lista vacía.Si
nS
se aplica a una lista con contenido, se puede realizar el procesamiento real. Para esto, necesitamos una segunda función, aquí en unawhere
cláusula-, para usar la recursividad, ya que nuestranS
no realiza un seguimiento de un elemento para comparar.Nombramos esta función
g
. Funciona comparando su primer argumento con el encabezado de la lista que se le ha dado, y descartando el encabezado si coinciden y llamándose a sí mismo con el primer argumento anterior. Si no lo hacen, agrega la cabeza a la cola, se pasa a través de sí misma con la cabeza como el nuevo primer argumento.Para usar
g
, le damos la cabeza del argumentonS
y la cola como sus dos argumentos.nS
ahora es de tipoEq a => [a] -> [a]
, toma una lista y devuelve una lista. Requiere que podamos verificar la igualdad entre los elementos, ya que esto se hace en la definición de la función.Luego, componimos las funciones
nS
y utilizamostranspose
el(.)
operador.Composición de funciones significa lo siguiente:
(f . g) x = f (g (x))
.En nuestro ejemplo,
transpose
gira una tabla 90 °,nS
elimina todos los elementos iguales secuenciales de la lista, en este caso otras listas (eso es lo que es una tabla), latranspose
gira hacia atrás ynS
nuevamente elimina elementos iguales secuenciales. Esto es esencialmente eliminar las filas duplicadas posteriores y las columnas.Esto es posible porque si
a
se puede verificar la igualdad (instance Eq a
), también lo[a]
es.En breve:
instance Eq a => Eq [a]
fuente