"Monitorizar" una imagen

9

El problema:

Este desafío proviene de un problema real que estaba teniendo. Tengo una configuración de monitor dual en el trabajo, y quería usar la siguiente imagen como fondo de pantalla:

Imagen ideal

Sin embargo, mis monitores tienen biseles bastante significativos, y cuando configuro mi fondo, se ve más o menos así, donde parece que el muelle (¿apliques?) Está roto:

Emitir imagen

Pude resolver esto haciendo una imagen con el centro cortado y luego estirándola de nuevo al tamaño original, como en la imagen a continuación:

Imagen de desafío


El reto:

Escriba un programa que tome una imagen y la "monitorice" para usarla con una configuración de monitor dual (es decir, elimina la sección central de la imagen, donde están los biseles). Las reglas son las siguientes:

  1. Debe ser un programa completo que acepte la imagen, ya sea como una ruta (argumento de cadena, etc.) o en forma de diálogo de selección de archivo.
  2. El programa debe tomar como entrada el número de líneas verticales (un píxel de ancho) para recortar desde el centro de la imagen.
  3. El recorte debe venir del centro (ancho) de la imagen original
  4. La imagen resultante se debe volver a escalar al tamaño original de la imagen de entrada. (O las mitades se pueden escalar individualmente, y luego concatenarse, o concatenarse y luego escalar. Escalar individualmente produce una mejor imagen / efecto, pero apenas se nota en el mundo real)
  5. Las imágenes de fondo son generalmente uniformes, por lo que para facilitar este desafío, las imágenes de entrada solo tendrán un número par de píxeles, y el número de líneas para eliminar también será igual.
  6. Este desafío es el código de golf: el código más corto en bytes gana

¡Buena suerte!

dberm22
fuente
2
1. No es muy claro en las imágenes cuál es la operación, porque están escaladas al mismo ancho. ¿Quizás reemplazar el primero y el último con imágenes del mismo tamaño que la del medio y rellenadas con blanco? 2. ¿Podemos usar cualquier forma de reescalado (lineal es probablemente el más barato) o tiene que ser específico (por ejemplo, cúbico, sinc, etc.)?
Peter Taylor
@PeterTaylor Según la regla 3, se supone que las imágenes de entrada y salida tienen el mismo ancho. Se redimensiona cada mitad a la mitad del ancho original y luego se concatena, o las mitades recortadas se concatenan y luego se reducen al tamaño original. Y sí, cualquier escala está bien.
dberm22
La oración que comienza con "Quizás" fue una sugerencia sobre cómo hacer que la pregunta sea más fácil de entender, no una interpretación sugerida del desafío. Yo mismo hice el cambio.
Peter Taylor
@ Peter Taylor Ahh, ya veo, eso lo hace más claro. Gracias.
dberm22
¿Podemos suponer que la imagen estará orientada al paisaje?
Scott Milner

Respuestas:

1

Octava, 85 bytes

@(f,n)imsave(imresize((o=imread(f))(:,[1:(end-n)/2,(end+n)/2:end],:),size(o)(1:2)),f)

Define una función anónima con fel nombre del archivo y nel número de columnas para eliminar. Como una función anónima requiere una sola expresión, se utiliza la asignación en línea, una característica que no está presente en MATLAB.

MATLAB, 98 bytes

Como beneficio adicional, también jugué una respuesta compatible con MATLAB. Curiosamente, esto es solo 13 bytes más, ya que la versión Octave necesita muchos paréntesis para analizar correctamente las asignaciones en línea.

function  m(f,n)
o=imread(f);imsave(imresize(o(:,[1:(end-n)/2,(end+n)/2:end],:),size(o(:,:,1))),f)
Sanchises
fuente
5

Matlab 2013, 150 bytes

Aquí está mi intento en Matlab. Definitivamente no será el código más corto, pero es un comienzo.

Advertencia, esto sobrescribe la imagen original, así que primero haga una copia.

Versión de golf

function  mi(f,n)
o=imread(f);
s=size(o);
imwrite([imresize(o(:,1:((s(2)-n)/2),:),[s(1),s(2)/2]) imresize(o(:,((s(2)+n)/2):end,:),[s(1),s(2)/2])], f);
end

Código no reflejado, con mejoras para tamaños de imagen impares y número impar de columnas

function  monitorizeImage( filename, num_columns )

orig = imread(filename);
orig_size = size(orig);

f = factor(orig_size(2));
origsize_iseven = f(1)==2;

f = factor(num_columns);
num_columns_iseven = f(1)==2;

odd_even_size_mismatch = xor(origsize_iseven,num_columns_iseven);

img_resized = imresize(orig,[orig_size(1) orig_size(2)+odd_even_size_mismatch]);

leftimg = img_resized(:,1:((orig_size(2)+odd_even_size_mismatch-num_columns)/2),:);
leftimg = imresize(leftimg,[orig_size(1),floor(orig_size(2)/2)]);
rightimg = img_resized(:,((orig_size(2)-odd_even_size_mismatch+num_columns)/2):end,:);
rightimg = imresize(rightimg,[orig_size(1),floor(orig_size(2)/2)]);

monitorized_image = [leftimg rightimg];
monitorized_image = imresize(monitorized_image,[orig_size(1),orig_size(2)+ ~origsize_iseven]);

[~, ~, ext] = fileparts(filename); 

imwrite(monitorized_image,strcat(filename(1:end-length(ext)),'_',num2str(num_columns),ext));

end
dberm22
fuente
Simplemente agregue a esto: las respuestas a los desafíos deben hacer un intento serio de optimización para el criterio de puntuación dado. En un desafío de código de golf como este, eso significa que se deben realizar mejoras obvias que reducirían la longitud del código.
Intente eliminar espacios no utilizados y espacios en blanco.
dkudriavtsev
@ ais523 Gracias. ¡Hasta 220 bytes!
dberm22
Además, cada variable de dos bytes es demasiado. La legibilidad no es importante, ¡así que refactorice, osetc., a cualquier otra letra del alfabeto! ¿Y por qué no simplemente volver a escribir la imagen en la imagen de entrada fpara guardar el conjunto strcat? (que, por cierto, puede reemplazar en ['',...]lugar de strcat(...))
Sanchises
@Sanchises Gracias, eso fue un remanente de la versión sin golf / mejorada. Nada en las reglas indicaba que no podía sobrescribir, o que necesitaba tener salidas con nombres bonitos. Gracias ... ¡eso disminuyó el conteo de bytes en 70 bytes!
dberm22
3

Wolfram Language, 134 , 127 , 119 111 bytes

f[i_,c_]:=(d=ImageDimensions@i;ImageAssemble[ImageTake[i,a=All,#]&/@{{0,e=-#&@@d/2-c/2},{-e,a}}]~ImageResize~d)

Crea una función fque toma una imagen como la primera entrada (como un símbolo en Mathematica o Wolfram Cloud) y un número entero como la segunda entrada.

Sin golf :

f[image_,columns_]:=(  (*Define Function*)
    d=ImageDimensions[image];  (*Get image dimensions*)
    e=d[[1]]/2+columns/2;  (*Add half the image width to half the number of removed columns*)
    ImageResize[ImageAssemble[Map[ImageTake[i,All,#]&,{{0,-e},{e,All}}]],d]  (*Map the function onto a list with the desired column ranges and merge and scale the resulting image*)
)

Técnicamente, no funcionará correctamente si cualquiera de las dimensiones de la imagen supera los 362.880 píxeles, pero supongo que está bien, ya que eso está muy fuera del alcance del problema (y algunas computadoras). ¡Fijo!

Scott Milner
fuente
2

PHP, 206 bytes

($c=imagecopyresized)($t=imagecreatetruecolor($w=imagesx($s=imagecreatefrompng($argv[1])),$h=imagesy($s)),$s,0,0,0,0,$v=$w/2,$h,$x=$v-$argv[2]/2,$h);$c($t,$s,$v,0,$w-$x,0,$v,$h,$x,$h);imagepng($t,$argv[3]);

toma tres argumentos de línea de comando: nombre del archivo de origen, número de líneas para recortar y nombre de archivo de destino. Corre con -r.

Es posible que desee utilizar en imagecopyresampledlugar de imagecopyresized(+2 bytes) para un mejor resultado.

sin golf

$s=imagecreatefrompng($argv[1]);    # load source image
$w=imagesx($s);$h=imagesy($s);      # get image dimensions
$t=imagecreatetruecolor($w,$h);     # create target image
$v=$w/2;                            # $v = half width
$x=$v-$argv[2]/2;                   # $x = width of remaining halves
                                    # resize and copy halves:
imagecopyresized($t,$s, 0,0,    0,0,$v,$h,$x,$h);
imagecopyresized($t,$s,$v,0,$w-$x,0,$v,$h,$x,$h);
imagepng($t,$argv[3]);              # save target image

Podría guardar 9 bytes más enviando el resultado PNG a STDOUT ... pero ¿para qué?

Tito
fuente
"Podría ahorrar 9 bytes más enviando el resultado PNG a STDOUT ... pero ¿para qué?" Entonces podrías correr algo como php -r image.php image.png 1 > output.png, ¿verdad?
ʰᵈˑ