"Monitorar" uma imagem

9

O problema:

Esse desafio vem de um problema real que eu estava tendo. Eu tenho uma configuração de monitor duplo no trabalho e queria usar a seguinte imagem como papel de parede:

Imagem ideal

No entanto, meus monitores têm molduras bastante significativas e, quando defino meu plano de fundo, é algo parecido com isto, onde o píer aparece (mais aparente?) Para ser quebrado:

Imagem da edição

Consegui resolver isso criando uma imagem com o centro recortado e depois esticando-a de volta ao tamanho original, como na imagem abaixo:

Imagem do Desafio


O desafio:

Escreva um programa que capte uma imagem e a "monitore" para uso com uma configuração de monitor duplo (ou seja, exclui a seção central da imagem, onde estão os painéis). As regras são as seguintes:

  1. Ele deve ser um programa completo que aceite a imagem, como um caminho (argumento de cadeia, etc.) ou na forma de uma caixa de diálogo de seleção de arquivos.
  2. O programa deve ter como entrada o número de linhas verticais (um pixel de largura) para recortar do centro da imagem
  3. O corte deve vir do centro (largura) da imagem original
  4. A imagem resultante deve ser redimensionada novamente para o tamanho original da imagem de entrada. (As metades podem ser dimensionadas individualmente e, em seguida, concatenadas ou concatenadas e, em seguida, dimensionadas. A escala individual produz uma melhor imagem / efeito, mas dificilmente é perceptível no mundo real)
  5. As imagens de plano de fundo geralmente são uniformes; portanto, para facilitar esse desafio, as imagens de entrada terão apenas um número par de pixels e o número de linhas a serem removidas também será uniforme.
  6. Esse desafio é o código de golfe - o código mais curto em bytes ganha

Boa sorte!

dberm22
fonte
2
1. Não é muito claro nas fotos qual é a operação, porque elas são dimensionadas para a mesma largura. Talvez substitua a primeira e a última por imagens do mesmo tamanho que a do meio e preenchidas com branco? 2. Podemos usar qualquer forma de redimensionamento (linear é provavelmente o mais barato) ou precisa ser específico (por exemplo, cúbico, sinc, etc.)?
22420 Peter
@ Petereter De acordo com a regra 3, as imagens de entrada e saída devem ter a mesma largura. Cada metade é redimensionada para metade da largura original e concatenada ou as metades cortadas são concatenadas e redimensionadas para o tamanho original. E sim, qualquer redimensionamento é bom.
precisa saber é o seguinte
A frase que começou "Talvez" foi uma sugestão de como tornar a pergunta mais fácil de entender, não uma interpretação sugerida do desafio. Eu mesmo fiz a mudança.
22416 Peter
@ PeterTaylor Ahh, entendo, isso fica mais claro. Obrigado.
precisa saber é o seguinte
Podemos assumir que a imagem será orientada para a paisagem?
22875 Scott Scottner

Respostas:

1

Oitava, 85 bytes

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

Define uma função anônima com fo nome do arquivo e no número de colunas a serem removidas. Como uma função anônima exige uma única expressão, a atribuição em linha é usada, um recurso não presente no MATLAB.

MATLAB, 98 bytes

Como bônus, também joguei uma resposta compatível com o MATLAB. Curiosamente, este é apenas 13 bytes a mais, pois a versão Octave precisa de muitos parênteses para analisar corretamente as atribuições em linha.

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

Matlab 2013, 150 bytes

Aqui está minha tentativa no Matlab. Definitivamente não será o código mais curto, mas é um começo.

Aviso, isso substitui a imagem original; portanto, faça uma cópia primeiro.

Versão Golfed

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 Ungolfed, com melhorias para tamanhos de imagem ímpares e número ímpar de colunas

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
fonte
Apenas adicionando a isso: as respostas aos desafios devem fazer uma tentativa séria de otimizar para o critério de pontuação fornecido. Em um desafio de código-golfe como esse, isso significa que qualquer melhoria óbvia que reduziria o tamanho do código deve ser feita.
Tente remover espaços não utilizados e espaços em branco.
precisa saber é o seguinte
@ ais523 Obrigado. Até 220 bytes!
precisa saber é o seguinte
Além disso, todas as variáveis ​​de dois bytes são muitas. A legibilidade não é importante, portanto refatorar osetc. para qualquer outra letra do alfabeto! E por que não escrever a imagem de volta na imagem de entrada fpara salvar o todo strcat? (que, aliás, você pode substituir por ['',...]em vez de strcat(...))
Sanchises
Obrigado, isso foi uma sobra da versão não-destruída / aprimorada. Nada nas regras afirmava que não poderia sobrescrever ou que precisava ter saídas bem nomeadas. Obrigado ... que diminuiu a contagem de bytes em 70 bytes!
precisa saber é o seguinte
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)

Cria uma função fque obtém uma imagem como a primeira entrada (como um símbolo no Mathematica ou na Wolfram Cloud) e um número inteiro como a segunda entrada.

Ungolfed :

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*)
)

Tecnicamente, ele não funcionará corretamente se qualquer uma das dimensões da imagem exceder 362.880 pixels, mas presumo que esteja tudo bem, pois isso está muito fora do escopo do problema (e alguns computadores). Fixo!

Scott Milner
fonte
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]);

usa três argumentos de linha de comando: nome do arquivo de origem, número de linhas a serem cortadas e nome do arquivo de destino. Corra com -r.

Você pode usar em imagecopyresampledvez de imagecopyresized(+2 bytes) para obter um resultado melhor.

destroçado

$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

Eu poderia salvar mais 9 bytes enviando o resultado PNG para STDOUT ... mas para quê?

Titus
fonte
"Eu poderia salvar mais 9 bytes enviando o resultado PNG para STDOUT ... mas para quê?" Então você pode executar algo como php -r image.php image.png 1 > output.png, certo?
ʰᵈˑ