# Intro (semi fictional)

I'm the solo developer of a game, I'm already struggling with character design as is. Hence I've thought of a smart solution, I'll just use images for regular monsters, outline them a bit and suddenly they are boss monsters! That will save me from thinking up new bosses yay.
However, I have approximately 100 monster designs already and I wouldn't like duplicating them all and manually drawing an outline to the images...

# Challenge

Given a file name (of a PNG file) as input, you should write a program/function which will draw an outline around every non-transparent pixel. The program/function should save the output file to a new file called a.png

# What does outlining mean

Outlining is the process of adding non-transparent pixels in the place of transparent pixels, around pixels which were non-transparent already. Any transparent pixel has an opacity of exactly 0%, anything else is defined as non-transparent. Any pixel which will be outlined will have an opacity of 100%, aka the alpha channel of that pixel will be 255.

# Input

Your program/function should take 3 variables as input. Feel free to provide these as function parameters, read them from stdin or any other method which suits you best.

The first variable is the file name, which is always a PNG file.
The second variable is the outline colour, which is a round integer, you can also take the colour from 3 separate r,g,b byte values.
The third variable is the outline width, also an integer.

# Outline width

The width of the outline equals the maximum distance any transparent pixel should have to a non-transparent pixel in order to be outlined. The distance is calculated using the Manhattan distance between two points.
If the input image has only 1 non-transparent pixel, at [0,0] and the outline width is 2, then the following pixels will be coloured: [0,1] [0,-1] [1,0] [-1,0] [1,1] [-1,-1] [1,-1] [-1,1] [2,0] [-2,0] [0,2] [0,-2], for these have a manhattan distance of 2 or less from the coloured pixel

# Test cases

The following test cases are scaled up 7 times for visibility, so every block of 7 pixels should be treated as a single pixel

These are the input images used for the test cases:

input1.png


input2.png


input3.png


These are the actual test cases:

input1.png, 0xFF0000, 0


input1.png, 0xFF0000, 1


input1.png, 0xFF0000, 2


input1.png, 0xFF0000, 3


input1.png, 0xFF0000, 10


input2.png, 0xFF0000, 2


input3.png, 0x000000, 2


This is , standard loopholes apply! Feel free to submit your own images as test cases, since these pixel images aren't very creative ;)

• Could the color also be taken as three separate r,g,b values? – flawr May 5 '16 at 12:26
• @flawr also fine with me – Bassdrop Cumberwubwubwub May 5 '16 at 12:42
• I assume you enlarged the images in the challenge description. Can you also post the ones with the original size? – flawr May 5 '16 at 12:46
• The PNG image requirement ruins the challenge. – 12Me21 Mar 9 '18 at 18:13

# Matlab, 202 bytes

function f(i,r,g,b,n);[i,~,a]=imread(i);[x,y]=ndgrid(abs(-n:n));d=permute([r,g,b,255]',3:-1:1);I=cat(3,i,a);J=uint8(bsxfun(@times,~~convn(a,x+y<=n,'s')&~a,d))+I;imwrite(J(:,:,1:3),'a.png','Al',J(:,:,4))


As always:

Convolution is the key to success.

The function can be called like so:

f('my_image.png', red_int, green_int, blue_int, dist)


Commented:

function f(i,r,g,b,n)
[x,y]=ndgrid(abs(-n:n));             %computations for convolution kernel
d=permute([r,g,b,255]',3:-1:1);      %create 'pixel' that will be inserted
I=cat(3,i,a);                        %concatenate image and alpha channel
J=uint8(bsxfun(@times,~~convn(a,x+y<=n,'s')&~a,d))+I; %find border via convolution of kernel, insert pixels and recombine with original
imwrite(J(:,:,1:3),'a.png','Al',J(:,:,4)) %write file


# PHP, 559 chars

## Ungolfed

<?php
error_reporting(0);
$p=$argv[1];
$img = ImageCreateFromPng($p);
$width = imagesx($img);
$height = imagesy($img);
$new = ImageCreateFromPng($p);
alphaFix($img); alphaFix($new);
$inv = '2130706432'; for($w=0;$w<$width;$w++) for($h=0;$h<$height;$h++) {$color = ImageColorAt($img,$w, $h); if($color != $inv) for($x=0;$x<$width;$x++) for($y=0;$y<$height;$y++) { if(abs($h - $y) + abs($w - $x) <= intval($argv[3]))
{
$_color = ImageColorAt($img, $x,$y);
if($_color ==$inv)
imagesetpixel($new,$x, $y, hexdec($argv[2]));
}
}
}
imagepng($new, str_replace(".png", ".border.png",$p));

function alphaFix(&$img) {$background = imagecolorallocate($img, 0, 0, 0); imagecolortransparent($img, $background); imagealphablending($img, false);
imagesavealpha($img, true); } ?>  ## Golfed <?error_reporting(0);$j=$argv[1];$g=ImageCreateFromPng($j);$e=imagesx($g);$b=imagesy($g);$l=ImageCreateFromPng($j);a($g);a($l);$f='2130706432';for($m=0;$m<$e;$m++)for($l=0;$l<$b;$l++){$d=ImageColorAt($g,$m,$l);if($d!=$f)for($k=0;$k<$e;$k++)for($i=0;$i<$b;$i++){if(abs($l-$i)+abs($m-$k)<=intval($argv[3])){$c=ImageColorAt($g,$k,$i);if($c==$f)imagesetpixel($l,$k,$i,hexdec($argv[2]));}}}imagepng($l,str_replace(".png",".border.png",$j));function a(&$g){$a=imagecolorallocate($g,0,0,0);imagecolortransparent($g,$a);imagealphablending($g,0);imagesavealpha($g,1);}


## Syntax

php outline.php "image1.png" 0xFF0000 1
|           |    |
|           |    *- Border Size
|           *------ Color HEX
*------------------ Image Name


## Examples

I made an Imgur album, because I slightly changed the images and there you can also see the arguments I passed my script.