9
\$\begingroup\$

The Problem:

This challenge comes from a real problem I was having. I have a dual monitor setup at work, and I wanted to use the following image as my wallpaper:

Ideal Image

However, my monitors have quite significant bezels, and when I set my background, it looks something like this, where the pier appears (appiers?) to be broken:

Issue Image

I was able to solve this by making an image with the center cut out of it, and then stretching it back to the original size, as in the image below:

Challenge Image


The Challenge:

Write a program that takes in an image and "monitorizes" it for use with a dual monitor setup (i.e. deletes the center section of the image, where the bezels are). The rules are as follows:

  1. It must be a full program that accepts the image, either as a path (string argument, etc), or in the form of a file chooser dialog.
  2. The program must take as an input the number of vertical lines (one pixel in width) to crop out from the center of the image
  3. The cropping must come from the center (width-wise) of the original image
  4. The resultant image must be re-scaled back to the original size of the input image. (Either the halves can be scaled individually, and then concatenated, or concatenated and then scaled. Scaling individually produces a better image/effect, but is hardly noticeable in the real world)
  5. Background images are generally even, so to make this challenge easier, input images will only have an even number of pixels, and number of lines to remove will only be even as well.
  6. This challenge is code golf - shortest code in bytes wins

Good Luck!

\$\endgroup\$
  • 2
    \$\begingroup\$ 1. It's not very clear from the pictures what the operation is, because they're scaled to the same width. Perhaps replace the first and last one with images that are the same size as the middle one and padded with white? 2. Can we use any form of rescaling (linear is probably cheapest) or does it have to be a specific one (e.g. cubic, sinc, etc.)? \$\endgroup\$ – Peter Taylor Apr 6 '17 at 20:28
  • \$\begingroup\$ @PeterTaylor As per rule 3, the input and output images are supposed to be the same width. Either each half is resized to half the original width, and then concatenated, or the cropped halves are concatenated, then scaled back to the original size. And yes, any scaling is fine. \$\endgroup\$ – dberm22 Apr 6 '17 at 20:49
  • \$\begingroup\$ The sentence beginning "Perhaps" was a suggestion for how to make the question easier to understand, not a suggested interpretation of the challenge. I've made the change myself. \$\endgroup\$ – Peter Taylor Apr 6 '17 at 22:51
  • \$\begingroup\$ @PeterTaylor Ahh, i see, That makes it clearer. Thanks. \$\endgroup\$ – dberm22 Apr 7 '17 at 11:45
  • \$\begingroup\$ Can we assume that the image will be landscape oriented? \$\endgroup\$ – Scott Milner Apr 7 '17 at 18:54
1
\$\begingroup\$

Octave, 85 bytes

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

Defines an anonymous function with f the file name, and n the number of columns to remove. Since an anonymous function requires a single expression, inline assignment is used, a feature not present in MATLAB.

MATLAB, 98 bytes

As a bonus, I also golfed a MATLAB compatible answer. Interestingly, this is only 13 bytes longer, since the Octave version needs a lot of parentheses to correctly parse the inline assignments.

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

Matlab 2013, 150 bytes

Here is my attempt in Matlab. Definitely won't be the shortest code, but it's a start.

Warning, this overwrites the original image, so make a copy first.

Golfed Version

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

Ungolfed Code, with improvements for odd image sizes and odd number of columns

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
\$\endgroup\$
  • \$\begingroup\$ Just adding to this: answers to challenges must make a serious attempt at optimising for the given scoring criterion. In a code-golf challenge like this one, that means that any obvious improvements that would reduce the length of the code must be made. \$\endgroup\$ – user62131 Apr 6 '17 at 20:15
  • \$\begingroup\$ Try removing unused spaces and whitespace. \$\endgroup\$ – dkudriavtsev Apr 6 '17 at 20:27
  • \$\begingroup\$ @ais523 Thanks. Down to 220 bytes! \$\endgroup\$ – dberm22 Apr 6 '17 at 21:09
  • \$\begingroup\$ Also, every two-byte variable is one too many. Readability is not important, so refactor os etc. to any other letter in the alphabet! And why not just write the image back to to the input image f to save the whole strcat? (which, incidentally, you can replace by ['',...] rather than strcat(...)) \$\endgroup\$ – Sanchises Apr 6 '17 at 21:09
  • \$\begingroup\$ @Sanchises Thanks, that was a leftover from the ungolfed/improved version. Nothing in the rules stated it couldn't overwrite, or needed to have pretty named outputs. Thanks...that decreased byte count by 70 bytes! \$\endgroup\$ – dberm22 Apr 6 '17 at 21:16
3
\$\begingroup\$

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)

Creates a function f that takes an image as the first input (as a symbol in Mathematica or the Wolfram Cloud), and an integer as the second input.

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

Technically, it won't work properly if either of the image dimensions exceed 362,880 pixels, but I assume that's okay, since that is way outside the scope of the problem (and some computers). Fixed!

\$\endgroup\$
2
\$\begingroup\$

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]);

takes three command line arguments: source file name, number of lines to crop and target filename. Run with -r.

You may want to use imagecopyresampled instead of imagecopyresized (+2 bytes) for a better result.

ungolfed

$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

I could save 9 more bytes by sending the PNG result to STDOUT ... but what for?

\$\endgroup\$
  • \$\begingroup\$ "I could save 9 more bytes by sending the PNG result to STDOUT ... but what for?" Then you could run something like php -r image.php image.png 1 > output.png, right? \$\endgroup\$ – ʰᵈˑ Apr 10 '17 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.