function photoToDots( src_file, dst_file, diameter ) % Load image and convert to gray scale src_img = rgb2gray(im2double(imread(src_file))); % Calculate the dimensions of the output image rows = round(size(src_img, 1) / diameter); cols = round(size(src_img, 2) / diameter); % Resize, normalize and invert the source image src_img = imresize(src_img, [rows cols], 'bicubic'); src_img = (src_img - min(src_img(:))) / (max(src_img(:) - min(src_img(:)))); src_img = 1 - src_img; % Create an empty destination image dst_img = zeros((rows+1)*diameter, (cols+1)*diameter); % Draw the dots for i = 1:cols for j = 1:rows x = i * diameter; y = j * diameter; % The size of the dot is determined by the darkness of the original pixel r = sqrt(src_img(j, i) * diameter^2 / pi); dst_img = addDot(dst_img, x, y, r); end end % If the output image is a png, store a transparent image. if strcmpi(dst_file(end-3:end), '.png') imwrite(zeros(size(dst_img)), dst_file, 'Alpha', dst_img); % Otherwise, just store a grayscale image. else dst_img = 1 - dst_img; imwrite(dst_img, dst_file); end end function I = addDot(I, x, y, r) % Determine the dimensions of the dot w = ceil(r) + (x - floor(x)) - 1; h = ceil(r) + (y - floor(y)) - 1; % Create a meshgrid [X,Y] = meshgrid(-h:h,-w:w); % Create the dot (the division by 2 is to smooth the edge) D = r-sqrt(X.^2+Y.^2); C = min(max(D/2, 0), 1); % Calculate the position of the patch in the destination image image X = x+X; Y = y+Y; % Calculate the indexes in the destination image idx = (X-1) * size(I,1) + Y; % Add the dot to the original image I(idx) = max(I(idx), C); end