-
Notifications
You must be signed in to change notification settings - Fork 5
Day four #15
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?
Day four #15
Changes from all commits
95626c6
c489e10
286e45e
362287e
b34a554
5641cc0
da4478d
5246449
b806b49
a92c830
8ac8a88
d1b9c6e
b91272a
78cf5de
d7d83f7
085b64c
b55268c
c10585e
e8b2726
28f6a99
85a04a3
6d85e0c
75bf05f
46c5eac
d2fd907
10401e4
d0deb99
7b64576
7e3142d
bceb6d4
9791a0d
a1bcf05
300dd3e
09a4145
b4cacda
55595d3
f55f0a9
86cb6cc
4fe766d
56cdca5
5f8521b
b5e05ed
0a6562e
ebff65c
f78a190
e44f95f
617ea59
e77e7dc
db26c6e
4b4a517
20e03fb
1ee5555
f6f9cd1
81a2cf2
a1c728d
b9f02ca
7226f0d
a5ab5ec
4419a8e
4e3f3eb
9fc33f0
f1681fb
596ac82
976b96d
0c21dd1
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 |
|---|---|---|
| @@ -1,61 +1,40 @@ | ||
|  Lab 04: Bitmap Transformer | ||
| === | ||
|
|
||
| ## To Submit this Assignment | ||
| * have team leader fork this repository | ||
| * have team leader add team members as collaborators to the team fork | ||
| * team members should clone team fork | ||
| * write all of your code in a directory name `bitmap-` + `<team name>` **e.g.** `bitmap-weasels` | ||
| * submit a pull request to this repository when done | ||
| * each person will submit a link to their own PR in canvas | ||
| * each person write a question and observation on canvas | ||
|
|
||
| ## Learning Objectives | ||
| * students will be able to manipulate binary data using the node.js `Buffer` class | ||
| * students will be able to architect modular solutions to solving problems | ||
|
|
||
| ## Resources | ||
| * [Bitmap Specification](https://en.wikipedia.org/wiki/BMP_file_format) | ||
| * [NodeJS Buffer docs](https://nodejs.org/api/buffer.html) | ||
|
|
||
| #### Feature Tasks | ||
|
|
||
| For this assignment you will be building a bitmap (`.bmp`) reader and transformer. It will read a bitmap in from disk, run one or more color transforms on the bitmap and then write it out to a new file. This project will require the use of node buffers in order to manipulate binary data. Your project should include tests, as well as a `package.json`, `.eslintrc`, `README.md`, and a `.gitignore`. Make sure to run all your code through eslint. The process will look something like this: | ||
|
|
||
| 1. open the original bitmap file using fs and read it into a buffer | ||
| 2. convert the buffer header data into a Javascript Object (using constructors) | ||
| 3. run a transform on the buffer directly | ||
| 4. write the buffer to a new file | ||
|
|
||
| The wikipedia article found here [Bitmap Specification](https://en.wikipedia.org/wiki/BMP_file_format) describes the byte specification of a "windows bitmap file." We'll be working with the simplest version, meaning no compression. | ||
|
|
||
| * your project should have three ***(or more)*** transforms | ||
| * invert the colors (***hint:*** subtract every color value from the max color value which is 255), | ||
| * grayscale the colors (***hint:*** multiply each color value by a constant, just make sure your values don't go over 255) | ||
| * (red|green|blue)scale the colors (***hint:*** same as above but only multiply one of the colors) | ||
|
|
||
| #### Bonus: | ||
| * ability to handle various sized bitmap | ||
| * ability to handle LE and BE computers with a single if statement | ||
| * utilizes a command line interface (CLI) | ||
| * CLI can select the transforms | ||
|
|
||
| #### Suggested Directory Structure (this is optional): | ||
| * suggested directory structure: | ||
| - **index.js** | ||
| - **lib** | ||
| - bitmap file helper | ||
| - **model** | ||
| - bitmap constructor | ||
| - color constructor | ||
| - **test** | ||
| - bitmap file helper test | ||
| - bitmap constructor test | ||
| - color constructor test | ||
|
|
||
| #### Rubric: | ||
| * **tests:** 3pts | ||
| * **package.json:** 2pts | ||
| * **read bitmap meta data:** 5pts | ||
| * **successfully apply transforms:** 5pts | ||
| * **project design and organization:** 5pts | ||
| -----Bitmap Transformer----- | ||
|
|
||
| Overview: Bitmap transformer reads a bitmap file and applies one of ten transformations to the file. The modified file is saved as a separate entity. | ||
| The project is separated into two major components and a test. Additionally, there is a directory of assets which contains the original bitmap image as well as the modified duplicates. | ||
|
|
||
| The directory branch is as follows: | ||
|
|
||
| bitmapper_ram-rod | ||
| | | ||
| |--assets | ||
| | | ||
| |--lib | ||
| | | ||
| |--model | ||
| | | ||
| |--node_modules | ||
| | | ||
| |--test | ||
|
|
||
| -----Directory Overview----- | ||
|
|
||
| ---assets--- | ||
|
|
||
| *Houses all bitmap originals and modified duplicates* | ||
|
|
||
| ---model--- | ||
|
|
||
| bitmap.js module: Exports the bitmapper object which models bitmaps as javaScript objects. The bitmapper objects properties are described below: | ||
|
|
||
| Bitmap : serves as an object constructor. All of bitmaps properties correspond to meta data that is interpreted from the bitmap image as buffer housing hexi-decimal values using node's native fs module. properties also hold information that indicates the start and end points of various sections of the file. The original buffer is stored as a property of the instantiated object. | ||
|
|
||
| Bitmap.newFile : method of the Bitmap constructor that takes a string as a parameter. The string will serve as the file name for a new image. The stored buffer in the object will be used to write the new file. | ||
|
|
||
| renderImage : Wrapper for node's native fs module. Takes a path, a callback and a file name as parameters. The path will be used with fs.readFile to retrieve a buffer from a bitmap file. The buffer will be instantiated as a new Bitmap object The callback will come from the transformer.js module. This dictates what type of transformation to apply to the buffer. Finally, the name will be passed to the instantiated Bitmap's newFile method. | ||
|
|
||
| ---lib--- | ||
|
|
||
| transformer.js module: exports the transform object which applies 1 of 10 different transformations to a Bitmap object that is passed as a parameter. The transform object properties are described below: | ||
|
|
||
| modify : Serves as the primary function in transformer.js. All other methods will serve as a wrapper for modify. Modify requires 4 parameters; a Bitmap object, and 3 callbacks. Each callback will be applied to one of the 3 portions of a hex color; red, green and blue. The Bitmap object is iterated over using the stored integers that represent the start and end position of the color palette. The iterations increment by 4. One for red, green, blue and the padding. The Bitmap's stored buffer uses it's readUInt8 method on i - 3, i - 2, and i - 1. to return a value between 0 and 255. Those values are then passed to the callbacks. The return of the call back is then written back into the buffer at it's relative position using Buffer.writeUint8. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| **/node_modules/* | ||
| **/vendor/* | ||
| **/*.min.js | ||
| **/coverage/* | ||
| **/build/* |
| 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,136 @@ | ||
| # Created by https://www.gitignore.io/api/osx,vim,node,macos,windows | ||
|
|
||
| ### 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 | ||
|
|
||
| ### 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 ### | ||
|
|
||
| # Icon must end with two \r | ||
|
|
||
| # Thumbnails | ||
|
|
||
| # Files that might appear in the root of a volume | ||
|
|
||
| # Directories potentially created on remote AFP share | ||
|
|
||
| ### 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 | ||
|
|
||
| ### 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,macos,windows |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| 'use strict'; | ||
|
|
||
| const bitmapper = require('./model/bitmap.js'); | ||
| const transform = require('./lib/transformer.js'); | ||
|
|
||
| let transformations = Object.keys(transform); | ||
| let fileName = 'palette-bitmap'; | ||
|
|
||
| console.log(bitmapper); | ||
|
|
||
| for(let i = 1; i < transformations.length; i++) { | ||
| bitmapper(`./assets/${fileName}.bmp`, transform[transformations[i]], `${fileName}-${transformations[i]}`); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| 'use strict'; | ||
|
|
||
| const transform = module.exports = {}; | ||
|
|
||
| transform.modify = (parent, blueCallback, greenCallback, redCallback) => { | ||
|
|
||
| const helper = (bmp, position) => (callback) => (...ind) => { | ||
|
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. This is a very interesting construct on how to do this so props for creativity. You may want to be careful that you aren't adding in complexity just to be complex and show off what you can do. There are definitely simpler ways to do this that will work just as well and won't add as many calls to the stack and layer this so much.
Author
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. I applied the helper to clean up the callback calls in the for loop. Originally it was a lot of content per line which made readability difficult. Now that I look at it, I definitely could consolidate the helper function into a single stack. That's how it was originally.
Author
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. Like this right? |
||
| let hexColors = [bmp.readUInt8(ind[0]), bmp.readUInt8(ind[1]), bmp.readUInt8(ind[2])]; | ||
|
|
||
| return bmp.writeUInt8(callback(...hexColors), position); | ||
| }; | ||
| let start = parent.colorTableStartPoint, end = parent.colorTableEndPoint; | ||
|
|
||
| for (let i = 3 + start; i < end; i+=4) { | ||
| helper(parent.buffer, i - 3)(blueCallback)(i-3, i-2, i-1); | ||
| helper(parent.buffer, i - 2)(greenCallback)(i-2, i-3, i-1); | ||
| helper(parent.buffer, i - 1)(redCallback)(i-1, i-2, i-3); | ||
| } | ||
| }; | ||
|
|
||
| transform.blueShift = function(buffer) { | ||
| transform.modify(buffer, | ||
| hexBlue => hexBlue, | ||
| () => 0, | ||
| () => 0 | ||
| ); | ||
| }; | ||
|
|
||
| transform.redShift = function(buffer) { | ||
| transform.modify(buffer, | ||
| () => 0, | ||
| () => 0, | ||
| hexRed => hexRed | ||
| ); | ||
| }; | ||
|
|
||
| transform.greenShift = function(buffer) { | ||
| transform.modify(buffer, | ||
| () => 0, | ||
| hexGreen => hexGreen, | ||
| () => 0 | ||
| ); | ||
| }; | ||
|
|
||
| transform.noGreen = function(buffer) { | ||
| transform.modify(buffer, | ||
| (blue) => blue, | ||
| () => 0, | ||
| (red) => red | ||
| ); | ||
| }; | ||
|
|
||
| transform.noBlue = function(buffer) { | ||
| transform.modify(buffer, | ||
| () => 0, | ||
| (green) => green, | ||
| (red) => red | ||
| ); | ||
| }; | ||
|
|
||
| transform.noRed = function(buffer) { | ||
| transform.modify(buffer, | ||
| (blue) => blue, | ||
| (green) => green, | ||
| () => 0 | ||
| ); | ||
| }; | ||
|
|
||
| transform.blackOut = function(buffer) { | ||
| transform.modify(buffer, | ||
| () => 0, | ||
| () => 0, | ||
| () => 0 | ||
| ); | ||
| }; | ||
|
|
||
| transform.whiteOut = function(buffer) { | ||
| transform.modify(buffer, | ||
| () => 255, | ||
| () => 255, | ||
| () => 255 | ||
| ); | ||
| }; | ||
|
|
||
| transform.greyScale = function(buffer) { | ||
| transform.modify(buffer, | ||
| (first, second, third) => (first + second + third) / 3, | ||
| (first, second) => second, | ||
| (first, second, third) => third | ||
| ); | ||
| }; | ||
|
|
||
| transform.invert = function(buffer) { | ||
| let helper = (val) => 255 - val; | ||
| transform.modify(buffer, | ||
| helper, | ||
| helper, | ||
| helper | ||
| ); | ||
| }; | ||
|
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. All the transforms look good. |
||
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.
This should be bitmap.renderImage() I believe as that allows it to create the files and bitmapper is just an object with properties not a function.