Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7e8a9b3
access bmp file path
Dec 1, 2017
a7e2647
trying to get pixel data for color table for bmp
Dec 1, 2017
1605359
writing inverse color transform function
Dec 2, 2017
af4d3d7
invert bitmap colors with invertColor function
Dec 2, 2017
7ac1097
creating new bmp file using modified color palette
Dec 2, 2017
f9ceb27
getting blue and yellow instead of white and black for color inverter…
Dec 2, 2017
e3c5f58
finish grayscale transform function
Dec 3, 2017
6c88415
trying to refactor code to pass color palette to transform function
Dec 3, 2017
d09cbec
fixed data persistence by saving function outputs to variables
Dec 3, 2017
8f6a68c
allow user to enter an array of more than one transform function name
Dec 3, 2017
8a6a787
trying out process.argv for CLI
Dec 4, 2017
236284e
finish CLI app for editing BMP files
Dec 4, 2017
54a0735
finish writing tests
Dec 4, 2017
2ce0735
fix linter errors, remove unnecessary variables, and correct number o…
Dec 6, 2017
e4c9ede
still trying to fix bug testing bitmap function
Dec 6, 2017
627fa45
trying to get args to reflect the array passed in through test file
Dec 8, 2017
e4bb58c
assign initial args value in test file then overwrite it with correct…
Dec 8, 2017
5007af7
trying to fix bug testing transformImage
Dec 13, 2017
6483906
remove console log
Dec 13, 2017
ed67054
refactoring code to separate index.js and imageTransformer function
Dec 13, 2017
02a491c
successfully separate image transform function from function call; te…
Dec 13, 2017
0a78629
fixing file structure so everything is in a lab-shannon folder
Dec 16, 2017
178854c
undo accidental overwrite of master README file
Dec 16, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Created by https://www.gitignore.io/api/osx,vim,node,linux,windows,visualstudiocode

### Linux ###
*~

# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*

# KDE directory preferences
.directory

# Linux trash folder which might appear on any partition or disk
.Trash-*

# .nfs files are created when an open file is removed but is still being accessed
.nfs*

### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Typescript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env


### OSX ###
*.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### Vim ###
# swap
[._]*.s[a-v][a-z]
[._]*.sw[a-p]
[._]s[a-v][a-z]
[._]sw[a-p]
# session
Session.vim
# temporary
.netrwhist
# auto-generated tag files
tags

### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history

### Windows ###
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db

# Folder config file
Desktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msm
*.msp

# Windows shortcuts
*.lnk

# End of https://www.gitignore.io/api/osx,vim,node,linux,windows,visualstudiocode
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
* [Bitmap Specification](https://en.wikipedia.org/wiki/BMP_file_format)
* [Buffer Docs](https://nodejs.org/api/buffer.html)

## Configuration
## Configuration
Configure the root of your repository with the following files and directories. Thoughfully name and organize any aditional configuration or module files.
* **README.md** - contains documentation
* **.gitignore** - contains a [robust](http://gitignore.io) `.gitignore` file
* **.gitignore** - contains a [robust](http://gitignore.io) `.gitignore` file
* **.eslintrc.json** - contains the course linter configuratoin
* **.eslintignore** - contains the course linter ignore configuration
* **package.json** - contains npm package config
Expand All @@ -30,37 +30,36 @@ For this assignment you will be building a bitmap (`.bmp`) transformer CLI. It w

#### Minimum Requirements
* The CLI should be architected using best modularization practices
* The CLI should require at least three arguments `input-file-path output-file-path transfrom-name`
* The CLI should require at least three arguments `input-file-path output-file-path transfrom-name`
* The CLI should support a minimum of three transforms
* The CLI should log useful Error messages if used incorrectly
* The CLI should log a success message on completion

## Testing
* Use TDD `describe` and `test` methods to define descriptive tests and increase readablity
## Testing
* Use TDD `describe` and `test` methods to define descriptive tests and increase readability
* Each `test` callback should aim to test a small well defined feature of a function
* Write tests to ensure each function behaves correctly with valid and invalid inputs
* The CLI should be tested without using `child_process` or any equivilant third party libraries

## Documentation
In your README.md describe the exported values of each module you have defined. Every function description should include it's arity (expected number of paramiters), the expected data for each parameter (data-type and limitations), and it's behavior (for both valid and invalid use). Feel free to write any additional information in your README.md.
In your README.md describe the exported values of each module you have defined. Every function description should include it's arity (expected number of parameters), the expected data for each parameter (data-type and limitations), and it's behavior (for both valid and invalid use). Feel free to write any additional information in your README.md.

## Tips
You will want to define a strategy for solving the problem before you begin to code. Once you have a strategy defined, you can break it down into steps that can be split into helper modules. Each helper module should solve a small specific problem. The main module should utilize the helper modules to execute your original strategy.

###### Example Strategy
###### Example Strategy
0. Gather user input (infile, outfile, and transform)
0. Read the input bitmap file using the fs module
0. Read the input bitmap file using the fs module
0. Parse the bitmap's buffer into object representing a bitmap (using a constructor)
0. Using metadata from the parsed bitmap object to run a transform on the buffer directly (mutate the colors)
0. Write the mutated buffer to the output file path

###### Transfrom Ideas
* Color Palette Transforms
* Invert
* Color Palette Transforms
* Invert
* Randomize
* Greyscale
* Black and White
* Darken or Lighten
* Add or Mutiply a Hue
* Add or Subtract Contrast

5 changes: 5 additions & 0 deletions lab-shannon/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
**/node_modules/*
**/vendor/*
**/*.min.js
**/coverage/*
**/build/*
26 changes: 26 additions & 0 deletions lab-shannon/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"env": {
"browser": true,
"node": true,
"commonjs": true,
"jest": true,
"es6": true
},
"globals": {
"err": true,
"req": true,
"res": true,
"next": true
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"no-console": "off",
"indent": [ "error", 2 ],
"quotes": ["error", "single", { "allowTemplateLiterals": true }],
"comma-dangle": ["error", "always-multiline"],
"semi": [ "error", "always" ]
}
}
1 change: 1 addition & 0 deletions lab-shannon/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The program alters an image (bmp format) using one of three provided transformation types and saves the new image as a different file. Three parameters are required: the file path of the image to be altered (must be a .bmp format), the desired output file path (with .bmp extension), and the name of the transform desired (invert, randomize, or greyscale). If a parameter is not supplied the program will return an error. If the transformation type is not one of the three provided an error will be thrown and no new image will be created.
34 changes: 34 additions & 0 deletions lab-shannon/__test__/bitmapTransformer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';

const imageTransformer = require(`../lib/imageTransformer.js`);

let args;

describe(`bitmapTransformer.js`, () => {
test(`imageTransformer.transformImage should return an edited image based on the transform operation provided if no errors are present`, () => {
expect(() => {
args = [`house.bmp`,`invert.bmp`,`invert`];
imageTransformer.transformImage(...args);
}).not.toThrow();
expect(() => {
args = [`house.bmp`,`greyscale.bmp`,`greyscale`];
imageTransformer.transformImage(...args);
}).not.toThrow();
expect(() => {
args = [`house.bmp`,`randomize.bmp`,`randomize`];
imageTransformer.transformImage(...args);
}).not.toThrow();
});
test(`imageTransformer.transformImage should return an error if the transform type provided is not one of the three options`, () => {
expect(() => {
args = [`house.bmp`,`randomize.bmp`,[blah]];
imageTransformer.transformImage(...args);
}).toThrow();
});
test(`imageTransformer.transformImage should return an error if fewer than three parameters are provided`, () => {
expect(() => {
args = [`house.bmp`,`randomize.bmp`];
imageTransformer.transformImage(...args);
}).toThrow();
});
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 9 additions & 0 deletions lab-shannon/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict';

const bitmapTransformer = require(`./lib/bitmapTransformer`);
const imageTransformer = require(`./lib/imageTransformer`);
const indexJS = module.exports = {};

let args = process.argv.slice(2);

imageTransformer.transformImage(args[0], args[1], args.slice(2));
69 changes: 69 additions & 0 deletions lab-shannon/lib/bitmapTransformer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use strict';

const fs = require(`fs`);
const bitmapTransformer = module.exports = {};

const BITMAP_FILE_HEADER_SIZE = 14; //in bytes
const DIB_HEADER_SIZE = 40; //in bytes
const COLOR_PALETTE_OFFSET = (BITMAP_FILE_HEADER_SIZE + DIB_HEADER_SIZE); //offset of where color palette starts
const PIXEL_TABLE_OFFSET = 10; //gives the offset of where the pixel data starts (i.e. end of color palette)

bitmapTransformer.readFile = (pathOfInput, callback) => {
fs.readFile(`${__dirname}/../asset/${pathOfInput}`,
(error, data) => {
if (error)
console.error(error);

callback(data);
}
);
};

bitmapTransformer.getColorPalette = (buffer) => {
let parsedBitmap = {};
parsedBitmap.buffer = buffer;
buffer.pixelTableOffset = buffer.readInt32LE(PIXEL_TABLE_OFFSET);
parsedBitmap.colorPalette = buffer.slice(COLOR_PALETTE_OFFSET, buffer.pixelTableOffset);

return parsedBitmap;
};

bitmapTransformer.renderNewFile = (outputPath, parsedBitmapData) => {
fs.writeFile(outputPath, parsedBitmapData, (error) => {
if (error)
console.error(error);
});
};


bitmapTransformer.greyscale = (colorPalette) => {
//Luminosity based grayscale: gray value = 0.21 × R + 0.72 × G + 0.07 × B
for (let i = 0; i < colorPalette.length; i += 4){
let weightedGrayscaleAvg = (colorPalette[i] * .11) + (colorPalette[i + 1] * .59) + (colorPalette[i + 2] * .3);
colorPalette[i] = weightedGrayscaleAvg;
colorPalette[i + 1] = weightedGrayscaleAvg;
colorPalette[i + 2] = weightedGrayscaleAvg;
}
};

bitmapTransformer.invert = (colorPalette) => {
//change blue values
for (let i = 0; i < colorPalette.length; i += 4){
// try to use .fill instead // colorPalette.fill(255 - colorPalette[i], 0);
colorPalette[i] = 255 - colorPalette[i];
}
//change green
for (let i = 1; i < colorPalette.length; i += 4){
colorPalette[i] = 255 - colorPalette[i];
}
//change red
for (let i = 2; i < colorPalette.length; i += 4){
colorPalette[i] = 255 - colorPalette[i];
}
};

bitmapTransformer.randomize = (colorPalette) => {
for (let i = 0; i < colorPalette.length; i += 4){
colorPalette[i] = Math.floor(Math.random() * 255);
}
};
33 changes: 33 additions & 0 deletions lab-shannon/lib/imageTransformer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

const bitmapTransformer = require(`./bitmapTransformer`);
const imageTransformer = module.exports = {};

imageTransformer.transformImage = (inputPath, outputPath, transforms) => {
if(!inputPath || !outputPath || transforms.length < 1){
throw new Error(`Please provide an input path, an output path, and at least one transformation type`);
}

bitmapTransformer.readFile(inputPath, (data) => {
let parsedBitmap = bitmapTransformer.getColorPalette(data);

for(let i = 0; i < transforms.length; i++){
if(transforms[i] === `greyscale`) {
bitmapTransformer.greyscale(parsedBitmap.colorPalette);
}
else if(transforms[i] === `randomize`){
bitmapTransformer.randomize(parsedBitmap.colorPalette);
}
else if(transforms[i] === `invert`){
bitmapTransformer.invert(parsedBitmap.colorPalette);
}
else{
throw new ReferenceError(`The transformation type must be 'invert', 'greyscale', or 'randomize'`);
}
}

bitmapTransformer.renderNewFile(outputPath, parsedBitmap.buffer);

console.log(`Success! Your new image has been created`);
});
};
Loading