%% Colton Watson
%% Math 2270
%% Last updated: May 7, 2018

%% Image Transformations Rotating, Shearing, and Scaling
%% Tested on GNU Octave, version 4.4.0, 

clc;
clear all;
close all;
pkg load image;

% I've had success with .jpg, .png, and .bmp files in the same directory as this 
% script, also I have not tested this with other files, so there is no guarantee
% it will work favorably. Large images will take a considerable amount of time
% to process since this program isn't optimized for image manipulation, it
% exists as a simple, practical example of transformations using matrices.

% Get the image, by user choice, make the image grayscale so it can be processed
% faster and more easily, then make the image an array of doubles.
 
[file,path] = uigetfile;

% If the user closed the file browser, just return nothing.
if (path == 0 || file == 0)
  return;
endif

imgdata = imread(fullfile(path, file)); 
imgdata = rgb2gray(imgdata);
imgdata = double(imgdata);

% Display the grayscale image.
figure('Name', 'Original Grayscale Image');
imshow(uint8(imgdata));

% Uncomment the next line to save the image in the current directory.
% imwrite(uint8(imgdata), "original.png");


% Transformation flags, and relevent data. 
%
% Set the flag to true for the image to be transformed with the indicated 
% transformation. Set the flag to false to not do that particular transformation.
% Transformations will create separate figures. 
%
% Rotations:
% theta - the angle to rotate the image clockwise, radians are expected.
%
% Shears:
% horiz_shear - double value that adjusts horizontal shearing. 
%               The default is 0, good results have been had with values 
%               ranging from 0.01~4, positive and negative.
% vert_shear  - double value that adjusts vertical shearing.
%               The default is 0, good results have been had with values 
%               ranging from 0.01~4, positive and negative.
%
% Contractions and expansions (scaling):
% horiz_scale - amount to scale the image in the horizontal direction.
%               If the scale is <=0, the image will essentially be a projection 
%               of the image on the vertical axis. (There will be nothing to see.)
% vert_scale  - amount to scale the image in the vertical direction.
%               If the scale is <=0, the image will essentially be a projection 
%               of the image on the horizontal axis. (There will be nothing to see.)

to_rotate   = false;
theta       = pi/4;

to_shear    = false;
horiz_shear = 0.6;
vert_shear  = 0.1;

to_scale    = false;
horiz_scale = 0.55;
vert_scale  = 1.2;


% Rotations
if(to_rotate)
  rot_image = math_rotate(imgdata, theta);
    
  figure('Name', 'Rotation');
  imshow(uint8(rot_image));
  
  % Uncomment the next line to save the image in the current directory.
  % imwrite(uint8(rot_image), "rotation.png");

endif

% Shearing
if(to_shear)
  shear_image = math_shear(imgdata, horiz_shear, vert_shear);
  
  figure('Name', 'Shear');
  imshow(uint8(shear_image));
  
  % Uncomment the next line to save the image in the current directory.
  % imwrite(uint8(shear_image), "shear.png");
endif

% Scaling
if(to_scale)
  scale_image = math_scale(imgdata, horiz_scale, vert_scale);
  
  figure('Name', 'Scale');
  imshow(uint8(scale_image));
  
  % Uncomment the next line to save the image in the current directory.
  % imwrite(uint8(scale_image), "scale.png");
endif