-
Notifications
You must be signed in to change notification settings - Fork 7
04-Lab (Hawa Steven Caleb) #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
a0c909b
d41b72e
2489d1a
38a98c2
800ebba
9e50f46
4a6a4de
c02b605
3275fcf
a7bb5ff
756b176
3989a1e
aeb4fc4
ab76ccf
392c7e6
9302765
5deef24
9c1272a
3bb8867
a1df353
32f3f2f
d03e677
a92458b
749685e
c3391fe
32c2b11
fc1886d
664f075
a2f1dac
7cf2b8b
5b2e204
480ca91
0ab2204
62c50c9
7edb5dd
9e12bc6
f2c6cfd
9cfcb62
290c7f7
6aa8d77
6f57281
a30035f
6d5d7f6
0ed29fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Bitmap Transformer | ||
| ### Written by Hawa Abdi, Steven Bateman, and Caleb Sattgast | ||
|
|
||
| The bitmap transformer is a simple Node-based app that will allow you to change the Code Fellows-provided palette-bitmap.bmp file's color table. | ||
|
|
||
| ### Usage | ||
|
|
||
| Clone down this repository, then navigate to the bitmap-steven-hawa-caleb directory in your terminal and run `npm i`. | ||
|
|
||
| Transform the image by running `node bitmap-transformer.js` plus any of the four following arguments: | ||
| * `invert` | ||
| * `grayscale` | ||
| * `bluescale` | ||
| * `psychedelic` | ||
|
|
||
| Each argument passed in will create a copy of the original bitmap with the appropriate transform applied. | ||
|
|
||
| ### Example | ||
|
|
||
| Running `node bitmap-transformer.js grayscale invert` will create a grayScaled-bitmap.bmp and an inverted-bitmap.bmp file in the img directory, found | ||
| in the root. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| { | ||
| "rules": { | ||
| "no-console": "off", | ||
| "indent": [ "error", 2 ], | ||
| "quotes": [ "error", "single" ], | ||
| "semi": ["error", "always"], | ||
| "linebreak-style": [ "error", "unix" ] | ||
| }, | ||
| "env": { | ||
| "es6": true, | ||
| "node": true, | ||
| "mocha": true, | ||
| "jasmine": true | ||
| }, | ||
| "ecmaFeatures": { | ||
| "modules": true, | ||
| "experimentalObjectRestSpread": true, | ||
| "impliedStrict": true | ||
| }, | ||
| "extends": "eslint:recommended" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
|
|
||
| # Created by https://www.gitignore.io/api/windows,macos,linux,node | ||
|
|
||
| ### Windows ### | ||
| # Windows image file caches | ||
| Thumbs.db | ||
| ehthumbs.db | ||
|
|
||
| # Folder config file | ||
| Desktop.ini | ||
|
|
||
| # Recycle Bin used on file shares | ||
| $RECYCLE.BIN/ | ||
|
|
||
| # Windows Installer files | ||
| *.cab | ||
| *.msi | ||
| *.msm | ||
| *.msp | ||
|
|
||
| # Windows shortcuts | ||
| *.lnk | ||
|
|
||
|
|
||
| ### macOS ### | ||
| *.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 | ||
|
|
||
|
|
||
| ### 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* | ||
|
|
||
| # 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 | ||
|
|
||
| # node-waf configuration | ||
| .lock-wscript | ||
|
|
||
| # Compiled binary addons (http://nodejs.org/api/addons.html) | ||
| build/Release | ||
|
|
||
| # Dependency directories | ||
| node_modules | ||
| jspm_packages | ||
|
|
||
| # 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| 'use strict'; | ||
|
|
||
| const cliInterpreter = require('./lib/cli-interpreter.js'); | ||
| const invert = require('./lib/invert-colors.js'); | ||
| const grayscale = require('./lib/grayscale-colors.js'); | ||
| const bluescale = require('./lib/bluescale-colors.js'); | ||
| const psychedelic = require('./lib/psychedelic.js'); | ||
|
|
||
| const transformArray = cliInterpreter(process.argv); | ||
|
|
||
| // Series of if statements checking for the words "invert," "grayscale," and "bluescale". If they were passed in, use the appropriate module method. | ||
| if (transformArray.some(function(element) { return element.toLowerCase() === 'invert'; })) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 great use of the |
||
| invert.createInvertedBitmap(function() { | ||
| console.log('Inverted colors of palette-bitmap.bmp.'); | ||
| }); | ||
| } | ||
|
|
||
| if (transformArray.some(function(element) { return element.toLowerCase() === 'grayscale'; })) { | ||
| grayscale.createGrayscaleBitmap(function() { | ||
| console.log('Grayscale colors of palette-bitmap.bmp.'); | ||
| }); | ||
| } | ||
|
|
||
| if (transformArray.some(function(element) { return element.toLowerCase() === 'bluescale'; })) { | ||
| bluescale.createBlueScaleBMP(function() { | ||
| console.log('Blue-scaled the colors of palette-bitmap.bmp.'); | ||
| }); | ||
| } | ||
|
|
||
| if (transformArray.some(function(element) { return element.toLowerCase() === 'psychedelic'; })) { | ||
| psychedelic.createPsychedelicBMP(function() { | ||
| console.log('Psyched the colors of palette-bitmap.bmp.'); | ||
| }); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| 'use strict'; | ||
|
|
||
| const gulp = require('gulp'); | ||
| const linter = require('gulp-eslint'); | ||
| const mocha = require('gulp-mocha'); | ||
|
|
||
| gulp.task('test', function() { | ||
| gulp.src('./test/*-test.js', {read: false}).pipe(mocha({reporter: 'spec'})); | ||
| }); | ||
|
|
||
| gulp.task('lint', function() { | ||
| return gulp.src(['**/*.js', '!node_modules/**']) | ||
| .pipe(linter()) | ||
| .pipe(linter.format()) | ||
| .pipe(linter.failAfterError()); | ||
| }); | ||
|
|
||
| gulp.task('dev', function() { | ||
| gulp.watch(['**/*.js', '!node_modules/**'], ['lint', 'test']); | ||
| }); | ||
|
|
||
| gulp.task('default', ['dev']); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| 'use strict'; | ||
|
|
||
| const fs = require('fs'); | ||
| const bmp = require(`${__dirname}/../model/bitmap-constructor.js`); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 - no need to use |
||
|
|
||
| module.exports = exports = {}; | ||
|
|
||
| exports.blueScaleColorTable = function(callback) { | ||
| fs.readFile(`${__dirname}/../../img/palette-bitmap.bmp`, function(err, data) { | ||
| var blueScaleBuffer = Buffer.from(data); | ||
| bmp(function(err, data) { | ||
| for (var index = 0; index < data.colorTable.length; index += 4) { | ||
| var blueAvg = parseInt(blueScaleBuffer[54 + index] + blueScaleBuffer[55 + index] + blueScaleBuffer[56 + index] / 3); | ||
| if (blueAvg > 255) blueAvg = 255; | ||
| blueScaleBuffer[54 + index] = blueAvg; | ||
| } | ||
| callback(null, blueScaleBuffer); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 great use of the NodeJS |
||
| }); | ||
| }); | ||
| }; | ||
|
|
||
| exports.createBlueScaleBMP = function(callback) { | ||
| exports.blueScaleColorTable(function(err, blueScaleBuffer) { | ||
| fs.writeFile(`${__dirname}/../../img/bluescale-bitmap.bmp`, blueScaleBuffer, function(err) { | ||
| if (err) throw err; | ||
| if (callback) callback(); | ||
| }); | ||
| }); | ||
| }; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| 'use strict'; | ||
|
|
||
| // Slices out all elements of the process.argv array that gets passed in after the 1st index, effectively storing all parameters passed in to running | ||
| // node bitmap-transformer.js <transforms> | ||
| const cliArguments = module.exports = function(args) { //eslint-disable-line | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 awesome command line arguments module! |
||
| if (args.length < 3) throw new Error('No arguments passed in.'); | ||
| return args.slice(2, args.length); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| 'use strict'; | ||
|
|
||
| const fs = require('fs'); | ||
|
|
||
| module.exports = exports = {}; | ||
|
|
||
| //Reading the bitmap image file, and storing the data collected in hex decimal values into the transformedBuffer variable. There are 4 bytes per pixel (RGBA). The transformerBuffer variable is collecting the raw buffer data from each set. In order to find the grayscale value, I looped through every 4 bytes of RGBA set and found the average of the RGB values only- excluding the alpha because it deals with transparency, and storing that into the grayscale variable. Then, I am using the writeUInt8 method ( writeUInt8(value, offset) ) to store the grayscale values and each set (4 bytes) of the collected buffer data. Lastly, we are writing the new values into the bitmap image file I created called ../img/grayscale-bitmap.bmp. | ||
| exports.grayscaleTransform = function(callback) { | ||
| fs.readFile(`${__dirname}/../../img/palette-bitmap.bmp`, function(err, data) { | ||
| var transformedBuffer = Buffer.from(data); | ||
| var grayValue; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 good use of a var declaration for later assignment |
||
| for (var i = 54; i < 1078; i+=4) { | ||
| grayValue = (transformedBuffer.readUInt8(i) + transformedBuffer.readUInt8(i+1) + transformedBuffer.readUInt8(i+2))/3; | ||
| transformedBuffer.writeUInt8(grayValue, i); | ||
| transformedBuffer.writeUInt8(grayValue, i+1); | ||
| transformedBuffer.writeUInt8(grayValue, i+2); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 great use of the |
||
| } | ||
| callback(null, transformedBuffer); | ||
| }); | ||
| }; | ||
|
|
||
| exports.createGrayscaleBitmap = function(callback) { | ||
| exports.grayscaleTransform(function(err, transformedBuffer) { | ||
| fs.writeFile(`${__dirname}/../../img/grayscale-bitmap.bmp`, transformedBuffer, function(err) { | ||
| if (err) throw err; | ||
| if (callback) callback(); | ||
| }); | ||
| }); | ||
| }; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| 'use strict'; | ||
|
|
||
| const fs = require('fs'); | ||
| const bmp = require(`${__dirname}/../model/bitmap-constructor.js`); | ||
|
|
||
| module.exports = exports = {}; | ||
|
|
||
| // Reads the buffer from the original image, stores a copy of it as invertedBuffer, then changes each value in the color table to be 255 minus | ||
| // its original value. It then calls the callback function passed in, returning null for errors and the new, rewritten buffer. | ||
| exports.invertColorTable = function(callback) { | ||
| fs.readFile(`${__dirname}/../../img/palette-bitmap.bmp`, function(err, data) { | ||
| if (err) throw err; | ||
| var invertedBuffer = Buffer.from(data); | ||
| bmp(function(err, data) { | ||
| for (var i = 0; i < data.colorTable.length; i++) { | ||
| invertedBuffer[54 + i] = 255 - data.colorTable[i]; | ||
| } | ||
| callback(null, invertedBuffer); | ||
| }); | ||
| }); | ||
| }; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 |
||
|
|
||
| // Performs a writeFile, creating a file called inverted-bitmap.bmp, using the invertedBuffer created from the invertColorTable method. | ||
| exports.createInvertedBitmap = function(callback) { | ||
| exports.invertColorTable(function(err, invertedBuffer) { | ||
| fs.writeFile(`${__dirname}/../../img/inverted-bitmap.bmp`, invertedBuffer, function(err) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 nice use of passing your |
||
| if (err) throw err; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 good error handling |
||
| if (callback) callback(); | ||
| }); | ||
| }); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| 'use strict'; | ||
|
|
||
| const fs = require('fs'); | ||
| const bmp = require(`${__dirname}/../model/bitmap-constructor.js`); | ||
|
|
||
| module.exports = exports = {}; | ||
|
|
||
| exports.psychedelicTransform = function(callback) { | ||
| fs.readFile(`${__dirname}/../../img/palette-bitmap.bmp`, function(err, data) { | ||
| var psychedelicBuffer = Buffer.from(data); | ||
| bmp(function(err, data) { | ||
| for (var index = 0; index < data.colorTable.length; index += 1) { | ||
| if (psychedelicBuffer[54 + index] > 200) { | ||
| psychedelicBuffer[54 + index] = 0; | ||
| } | ||
| } | ||
| callback(null, psychedelicBuffer); | ||
| }); | ||
| }); | ||
| }; | ||
|
|
||
| exports.createPsychedelicBMP = function(callback) { | ||
| exports.psychedelicTransform(function(err, psychedelicBuffer) { | ||
| fs.writeFile(`${__dirname}/../../img/psychedelic-bitmap.bmp`, psychedelicBuffer, function(err) { | ||
| if (err) throw err; | ||
| if (callback) callback(); | ||
| }); | ||
| }); | ||
| }; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| 'use strict'; | ||
|
|
||
| const fs = require('fs'); | ||
|
|
||
| // CreateBmp will read the palette-bitmap.bmp file, then create a colorTable array of the 1024 bytes that represent the bitmap file's color table. | ||
| // The color table is found by starting the offset after the bitmap file header and the DIB header. | ||
| // The bitmap file header is always 14 bytes. | ||
| // This particular bitmap file header identifies the file type as BM, which means the DIB header corresponds to Windows 3.1x, 95, NT, etc. | ||
| // This makes it a DIB Header with the name BITMAPINFOHEADER, which has a size of 40 bytes. | ||
| // We can double check our DIB Header size using the buffer method readInt32LE(14), which will read the signed integer 14 bytes in (where the DIB header starts). | ||
| // So, the bitmap file header and the DIB header are a combined total of 54 bytes, so our color table should start at the 54th position of our buffer. | ||
| // We know where the color table ends because the pixel array immediately follows the color table, and the pixel array can be found 10 bytes in to | ||
| // the bitmap file header using the buffer method readInt32LE(10), which will read the signed integer 10 bytes in. | ||
| // We get back the value 1078, so we know the pixel array begins at the 1078th location. | ||
| // We can double check that our colorTable is the correct size by checking how many colors this bitmap file is expected to have. | ||
| // The DIB BITMAPINFOHEADER contains this information at an offset of 46 bytes, so if we use the buffer method readInt32LE(46), we get back a value | ||
| // of 256, meaning this bitmap file has 256 colors. | ||
| // Since each color is 4 bytes, we would expect a color table to be (256 x 4 = 1024) bytes in size. This matches our expected range of 54 bytes to 1078 | ||
| // bytes (1078 - 54 = 1024), so we can be sure we have correctly selected the color table from our buffer. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 - fantastic comments! |
||
| const createBmp = module.exports = function(callback) { //eslint-disable-line | ||
| const bmp = {}; | ||
| fs.readFile(`${__dirname}/../../img/palette-bitmap.bmp`, function(err, data) { | ||
| if (err) throw err; | ||
| bmp.colorTable = data.slice(54, 1078); | ||
| return callback(null, bmp); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maschigokae @BatemanVO @abdih17 good callback pattern here |
||
| }); | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maschigokae @BatemanVO @abdih17
requirestatements look good, along with the separation of your transform helpers by containing them in alibdirectory