Week 1: January 15-January 20
Tuesday,
15 January:
Received
project assignment. Initial trepidation was followed buy inspiring visions
of
algorithms that could possibly be used. I immediately recognized the problem
of using VC++ with MFC,
along
with decompressing JPEGs.
Wednesday, 16 January:
Researched
info on the Internet concerning the file structure and compression/decompression
of
JPEGs. Saved one webpage depicting the file structure of the JPEG, complete
with hexadecimal byte values
that
indicated where segments of the file started and finished.
Thursday, 17 January:
Researched
info on the Internet concerning the structure of Bitmap files and how
to
read them. Obtained sample code in C which read a bitmap and drew it on
the screen.
Friday, 18 January:
Began
forays into the world of MFC programming. I found the website www.relisoft.com,
which
offered tutorials in MFC and API programming. Internet sources not sufficient
at this time. Must
contact
Dr. McVey to borrow copy of CS 350 textbook(s), and other related material
I can borrow. I also
began
to form the Plan of Attack, which will begin with developing the Windows
interface. Plan of Attack
to
be finalized on Monday, and submitted for approval at next meeting.
Saturday/Sunday 19-20 January:
Further
pondered options and strategies for Plan of Attack.
Week 2: January 21-January 27
Monday, January 21:
Completed
my resume, career path statement, and statemtent of CS philosophy
Tuesday, January 22:
Learned
what other people are doing for projects. I consider myself fortunate that
I
have a mere software devolopment project, and do not have to implement
controls, etc. on trains and robots. I also
learned
HTML in lab, which is great fun....
Friday, January 25:
Recieved
MFC textbooks and CDROMS from Dr. McVey. Read two chapters of the Deitel
text,
and understood the basics (I think). I will try it out tomorrow...
Saturday, January 26:
Successfully
compiled example program from text, also played around with window
size.
Also studied Deitel text more to glean more info on buttons, menus, etc...
Sunday, January 27:
Successfully
wrote and compiled first version of the interface. At this time,
it
is just a blank window, but I understand how the class hierarchy works
in MFC. In Prosise text, I found
definitive
info on making push-buttons in a frame window. Must study further...
Week 3: January 28-February 3
Monday, January 28:
Studied
the MFC CButton class, and implemented a single button in my bare frame
window. Clicking on the button produced a message box which indicated that
the button was clicked. At this point, I am still debating whether to actually
include push buttons in the frame window, use a user-drawn toolbar, or
use a menu-driven program that uses dialog boxes and child windows....
Tuesday, January 29:
Looked
at Microsoft Photo Editor in order to receive inspiration as to how to
design my interface. I recognized the neatness and efficiency of a menu-driven
application, and began to ponder the possibilities ....
Wednesday, January 30:
Heavy
research into Prosise and Deitel texts to determine how to make a menu.
In the evening, I came near to completion. I had all the menu definitions,
message handlers, and handler functions defined and ready to go, but had
trouble with mymenu.rc and resource.h. Ran out of time around midnight....
Thursday, January 31:
Menu
implementation is successful. All image editing functions I wrote at this
time spit out a message box when called from the menu. The problem from
last night was that I did not include resource.h in the interface2.cpp
source code. I came to that conclusion upon studying the infamous NASA
program from CS 205. Thank you Professor Blahnik! Webpage update also on
today's agenda, as well as studying predefined File-menu dialog boxes from
classes in "afxdlgs.h".... A screen capture may be up this weekend ....
Sunday, February 3:
Implemented
Open and SaveAs dialog boxes. Need to create custom boxes for brightness/contrast
control, zooming, and rotate functions. In this next week, I must finish
the interface, create a data structure for the pixels, and read a bitmap
file into this data structure and display it on the screen. I must get
a design for this structure on paper and discuss the path from here with
DCP this week. I would also like to show Dr. McVey my source code for the
interface and get her opinion as to its design.
Week 4: February 4 - February 10
Monday, February 4:
Attempted
to implement a custom dialog box in my interface. First attempts were met
with frustration, as I had omitted necessary function calls to create and
show the dialog box in the main window. Later that day, I was successful
using ShowWindow() in my code.
Tuesday, February 5:
Today,
I gave the class an update on how far I had come in my project. I appear
to be farther along than others, but not as far as the "superstars" in
the class (you know who you are...). Once again, I am in the middle of
the pack... Scrutinized the Prosise text for more tips on using dialog
boxes and more importantly the structures associated with the Windows Bitmap
image file.
Wednesday, February 6:
I did
extensive research on the Internet regarding the methods used to read and
manipulate Bitmap files. One webpage written by Ahmad Hafiz gave detailed
info about Windows bitmap files. Apparently, they are divided into 4 sections:
File Header, Info Header, Palette, and Image Data. Reading the bitmap seems
a relatively easy task once the developer uses C structs to classify the
header data. I am still fuzzy on what a "palette" is and why it is needed
in Bitmap files. I saw no mention of palettes in the JPEG material I ran
across. No matter, though, as I am excited to finally be gettin' down in
the "nitty-gritty" of this project!
Thursday, February 7:
In
the morning, I examined my MFC text for an explanation of what a palette
is and why it exists. Apparently, a palette is just the set of unique colors
that an image is constructed from. A palette is enclosed within a file
to ensure that the application displaying it does so with the appropriate
colors, to guarantee accurate drawing of the image. Given that 256-color
display is almost a standard, at least here on campus, I may not worry
too much about what palette is necessary.... Also, I attended WorkForce
2002 at Marquette University. I was able to get five of my resumes out
to various companies including Kohler, HK Systems, SBC Ameritech, and Kimberly
Clark. I was not able to do any more work today, since we did not return
from Milwaukee until Midnight.
Friday, February 8:
Met
with Dr. Pankratz, and discussed my progress on the project thus far. It
seems that he is pleased with my Plan of Attack and my attitude toward
this project. He gave me some pointers as to how I should continue my work,
and he interrogated me to see how solid my plan of attack was. I am relieved
that he is somewhat satisfied with my progress, and that adds fuel to the
fire of urgency as I attempt to get the bulk of the development done before
spring break...
Sunday, February 10:
Researched
pixel reading in C++. Internet searches provide a lot of useless junk,
mostly pertaining to GL programming, whatever that is. I discovered a method
on a "Blitz Basic" message board (what the hell is Blitz Basic, anyway?)
that makes use of bitwise operators to convert a single-byte pixel value
into 3 RGB values. As Dr. Pankratz had hinted to me, this is the answer
to my problem of reading pixels and displaying them with MFC's SetPixel().
Armed with this info, I can once again plunge forward in the design of
the CS460 Image Editor...
Week 5: February 11 - February 17
Monday, February 11:
Week
5 already? AAAHHHHH! Actually, I am for the most part, on track with this
grand adventure. Today I have coded the class BMPImage, and put it in a
header file BMPedit.h. The class, as promised contains the data structure
for the bitmap, all necessary variables, and a read-from-a-file function
at this time. I am still working out compile errors, though, and expect
to run it tomorrow....
Tuesday, February 12:
Got
the thing compiled. However, it does not seem to work the way I want it
to. While debugging the program to see if data were properly read, I discovered
just the opposite. Enlisting the cheerful assistance of Drs. Pankratz and
McVey, it has been determined as of today tha using C++ struct objects
to store header data is not going to work; using read() with structs has
been demonstrated today to NOT work, while reading in variables separately
HAS been successful. Dr. Pankratz also showed me that it is important to
actually KNOW what I'm looking for in a Bitmap file. Using DEBUG in DOS,
we were able to view and verify the file header contents, and also to verify
the size of the objects in the file header(s). There was also some discrepancy
between the data types I used from my sample code and what type names meant
in Win32.... I suspect that I will have to continue reading variables from
the file one at a time....
Wednesday, February 13:
I have
now fixed my code so that it can read the entire bitmap file into my "data
structure". All file and infoheader data had to be contained in separate,
independent variables. According to Dr. McVey, this is because reading
entire structs can only be successful if the file was created using structs.
Since I am working with files from many different sources, it would be
impossible to guarantee this, and therefore I must read all variables individually.
I have also successfully created a 2-D array using MFC CArray objects.
One array is an array of byte variables, which each array representing
a single scan line from the bitmap. The whole of the image data is an array
of scan line arrays, hence the 2-D array. Tomorrow I will write the data
to another file using the "SaveAs" menu call handler function to check
if I read the file correctly.
Thursday, February 14:
I created
the "write" function, which has successfully written the data from one
bitmap to another. I tested the function by comparing data values in debugging,
and also by opening the two bitmaps simultaneously. Upon my success, however,
rests a problem. Until now, I had assumed that using 8-bit pixel bitmaps
with 256 color palettes would be sufficient. However, a photo that was
a bitmap which I tried to open and rewrite turned out to be 24-bit RGB.
This means that each pixel was represented by 3 bytes, 1 each for R,G,
and B color values. Upon doing some quick research, I determined that I
must switch to using 24-bit RGB format because uncompressed JPEG data is
in 24-bit RGB. I will attempt the conversion tomorrow...
Friday, February 15:
After
some intial setbacks regarding the use of CArray objects, I have successfully
read and wrote, without error, a 24-bit RGB bitmap. The structure for the
image data consists of a "pixel" class that contains 3 BYTE-sized integers
which contain RGB values, an array of pixel class objects (which represents
the scan lines), and finally an array of scan lines. This conversion worked
to perfection, as evidenced by the simultaneous viewing of the bitmaps
in MS Photo Editor. Another reason for the switch to RGB is that the test
pics I create with MSPaint will be in 24-bit RGB, so there you go. Next
up is drawing the image, which I will try to work on this Saturday and
Sunday if time allows.....
Saturday/Sunday February 16-17:
Regrettably,
no work done this weekend. The combination of long work hours, a band concert,
and visitors from home has taken all my time. Back At it on Monday.....
Week 6: February 18 - February 25
Monday, February 18:
Today
I managed to draw a bitmap image onto the client area of my main window.
Only problem is that when the window repaints, the picture disappears.
After "asking around" I discovered that I must use the Windows device context
CPaintDC, as opposed to CClientDC, and do all drawing in OnPaint(). This
function handles all WM_PAINT messages, so when a window must be refreshed,
a message is passed to OnPaint(), which then calls my BMPDraw() function.
To activate a redraw from my program, I must call AfxGetMainWnd()->Invalidate(TRUE);
I must implement this tomorrow.
Tuesday, February 19:
Calling
my BMPDraw() function ONLY from OnPaint() has proven to be a success. My
program also appears to run faster after this change, which is good. I
also managed to create two functions that adjust the brightness of the
image, one for increasing, and one for decreasing brightness. Brightness
is adjusted, in short, by scaling the RGB values for each pixel up or down
by a set increment amount. That is, each RGB value is incremented by, say
10, or decremented by 10 for each call of a brightness adjusting function.
Limits must also be placed on how high a pixel can be Adjusted, so that
no wrapping of integers occurs. I also solved a problem with the scope
of my image pointer variable, but it may only be a temporary fix.
Wednesday, February 19:
Black-and-White
and Negative conversions were written. To convert a color to black and
white (gray scale), I discovered that one need only take the average of
a pixel's RGB values, and replace each RGB with the averaged result. I
came to this conclusion after seeing that any pixel drawn where R, G, and
B were equal came out to be shade of gray. It works rather well. Negative
images are created by replacing the RGB values with the result of 255-RGB(for
each RGB value). My function that turns images negative works to great
effect. Also researched info on adjusting contrast. More later. At night:
Added checking schemes so that user cannot close without making sure that
image can be saved if desired. Also added error checking in BMPRead() so
that the File_Open handler breaks if the file is invalid.
Thursday, February 20:
Met
with Dr. Pankratz to discuss my current situation. Received recommendations
for website, and how to go about documentation for the website and for
the "mini-presentation" in two weeks. Worked on updating web page, determined
what I need to add....
Sunday, February 24:
Posted
source code to the website. Beginning writing of documentation...
Week 7: February 25 - March 3
Monday, February 25:
Completed
documentation for both the BMPImage Class and the source code for the windows
interface. Began exploring methods for adjusting the contrast of an image.
Tuesday, February 26:
Started
writing code to adjust the contrast of an image. The general algorithm
is to first compute the mean luminance for all of the image's pixels, and
then to adjust each RGB value of each pixel up or down depending on its
relationship to the mean luminance value. So far, results are marginal,
but I am toying with variations on the main theme...
Wednesday, February 27:
After
some job hunting, I continued to attempt improvements on my contrast adjusting
algorithm. The adjusted image is comparable to a contrast adjustment on
MS Photo Editor, but not perfect. I have finalized the algorithm and decided
to move on for now... At night, I developed a function that causes the
image to be redrawn as a mirror of itself.
Thursday, February 27:
I added
a new feature today, one which adjusts the tint of an image. The user can
make an image have a red, green, or blue tint, as well as remove any trace
of that color from an image. I also toyed with ideas for writing the Rotate
and Magnification/Zoom features. I'm also debating adding a Resize feature,
but not sure yet.....
Saturday, March 2:
Started
coding the Windows dialog box stuff for the Rotate feature, and hit a snag
that some Windows gurus on the Net should be able to help me with......
Sunday, March 3:
Today
I'm working on an outline of topics for this weeks mini-presentation. Will
email to DCP for approval....
Week 8: March 4 - March 11
Monday, March 4:
Re-evaluated
my plans for doing the Rotate function. I have decided not to use a windows
dialog box control. I will now merely use only one function that rotates
an image 90 degrees. For the user to perform multiple or extended rotations,
the user would simply perform 2 or more 90 degree rotates. I have changed
my mind on this because I am limiting rotations to 90 degree intervals,
and a complex dialog box interface would be overkill in this case. Were
I to allow rotation by any degree, the dialog box control would be more
practical... Today I also continued to plan my walkthrough materials...
Tuesday, March 5:
Performed
the walkthrough. I will have to be more organized in my presentation next
time, so as to facilitate my public speaking, which is subpar.... On the
upside, I impressed the professors with the progress I have made so far,
and received a ton of suggestions on how to improve my program. Many of
the improvements suggested had to do with the usage of space in my code.
It was said, in essence, that my methods of modifying image data were sound,
but my usage of data structures to hold altered image data was wasteful
and caused the program to run slower than it should. It was suggested that
I modify an image by ONLY modifying the pixels on the screen, NOT altering
the data in memory then redrawing the whole image. I have no clue as of
yet how I can do this and be able to reclaim the data from the screen to
save it, but Dr. McVey gave me a great hint with regards to using the Windows
"Device Contexts" as areas in which to store and modify image data. Must
read more on the subject.....
Wednesday, March 5:
I fixed
the Mirror function so that it mirrors an image in place, as per Ms. Gibson's
suggestion during yesterday's walkthrough. It runs visibly faster than
the old version. I also scoured MSDN for detailed info on Windows DC's
(device contexts) and how they are used in Windows image processing....
Friday, March 7:
I had
a revelation today: I know how I can modify pixels directly on the screen.
Using the GetPixel() function, I can extract RGB data for each pixel, modify
it, and repaint the pixel back onto the DC from which it came. The only
problem is whether I can access CMainWindow's CPaintDC from outside functions.
If I can do that, then it's simpler than I thought. If not, I will have
to use a temporary DC, (class CDC, maybe another CPaintDC) to store modified
data and then in OnPaint() copy the data from the temporary DC to CPaintDC.
The extra image class object could be eliminated, and loads of processing
time would be saved!
Saturday,
March 8 - Sunday, March 17: SPRING BREAK
Monday, March 18 - Sunday, March 24:
During
this week I decided to undertake the streamlining of my program. With Dr.
McVey's help, I was able to use Windows Device Contexts to edit and redraw
images much, much faster. I now have the tricky task of completely adapting
the code so that it refreshes properly and also saves properly... I need
to devise a way to store an image in a "temporary" DC so that it can be
transferred to the window when the client area is invalidated.. My attempts
on Saturday met with failure....
Week 10: March 25 - March 31
Monday, March 25:
Today
met with more frustration regarding creating a new CDC object and drawing
an image on it in memory. My program kept asserting, and saying that the
DC was NULL. I must be missing a command somewhere along the line...
Tuesday, March 26:
More
frustration.... Cleaned up my code a little, though... Set up a meeting
with Dr. McVey....
Wednesday, March 27:
Today,
I ran across a JPEG library that is very compatible with the data structures
I use in my program... Once I learn how to link this library, I should
really be in business as far as JPEGs are concerned. My Meeting with Dr.
McVey also went well... We discoveredt the problem lied in part WHERE the
new DC was created, and we also missed a call to the CDC constructor...
However, there are more minor bugs to work through... For some reason,
when part of a dialog box overlaps the image in the window, that part does
not reappear when the dialog box closes... That is the most major bug right
now....
Thursday, March 28:
Met
with Dr. Pankratz today, and he told me among other things that I needed
to clean up my code... This I was aware of previously, but DCP told me
that Dr. McVey had some ideas for me, which will be helpful... I am also
glad to learn that my program will be a part of the CS curriculum in the
future! My work will help further the education of others!!
Week 11: April 1 - April 7
Tuesday, April 2:
Fixed
most major bugs in newest version of program. Image now properly refreshes
in all cases. The image also saves properly... I achieved this by having
the editing functions take their data from the temporary DC in memory as
opposed to the PaintDC, since the PaintDC can be considered unreliable,
due to the nature of multitasking.. This works like a charm. Got the rotate
function to "sort of" work, but unable to fix the bugs tonight....
Wednesday, April 3:
Demo'ed
the program for Dr. Pankratz today... He played around with it and tried
to "break" it to see if something needed to be addressed. Fortunately,
there was nothing that happened that I didn't expect to happen... Also
talked to Dr. McVey about scrollbar programming, and she told me to just
look at my MFC book for some code to use, due to the fact that I got other
things to address yet... (ZoomIn, ZoomOut, etc.)
Week 12: March Arpil 7 - April 14
Monday, April 8:
Today
I talked to Dr. McVey about what needed to be done to my code to "clean
it up" and left her hard copies so she can dissect them this week. At night,
I got the scrollbar installed, and it works well except for the fact that
it's slow as mud!!!! Next I have to work on image magnification...
Tuesday, April 9:
Started
on the ZoomIn function this evening. Having problems already, and I'm starting
to get worried. This was supposed to be easy!!! I'll drop in by McVey tomorrow
and have her look at my algorithm....
Wednesday, April 10:
McVey
gave me advice on what to do about my code... Basically, I have to cut
up the program into more files to speed compile time and aid readability.
I'll probably end up having .h and .cpp files for the Main Window, the
Dialog Boxes, and the BMPImage class. I also had her look at my code, which
was really bugging me by that afternoon. We fixed the problems. My algorithm
was correct, it was just a matter of where certain statements were placed.
I then had a problem with the redraw of a magnified image. The temporary
DC where it was stored was not storing the whole image. I solved the problem
by moving the image as a whole CBitmap structure to another DC, and giving
the temp_dc a clean CBitmap that matched the dimensions of the expanded
bitmap. This worked like a charm, but then the Undo algorithm asserted
on me, because of some Array-out-of-range error. This means I gotta save
the ORIGINAL dimensions of a bitmap and use them when the program reverts
to the original version. I'll do that Friday....
Friday, April 12:
I fixed
the UNDO problem, and managed to code the ZoomOut function correctly on
the first try! It all works pretty slick now, except for the Rotate function,
but I suspect it may be a similar problem to that of the resizing funcitons
(bitmap dimensions in the DC). Will do that tomorrow...
Saturday, April 13:
Between
shifts at work ("They call me the workin' man....") I got that blasted
Rotate function to work properly. Part of the problem was having the dimensions
for the temp_dc being wrong, and part of it was how I was moving the pixels.
Nonetheless, I got it working, and it works DAMN good! All I have to do
now is go through and test everything so that no errors fall through the
cracks. I also have to "cut up" my code as per McVey. Then I'll be pretty
much done!!!!!
Week 13: April 14 - April 21
Monday, April 15:
Today
I debugged some things in BMPEdit24.h that needed to be fixed. I managed
to get the error checking in BMPRead() to work again but making sure a
new image object was created, and all the old data cleared out, if there
was an error in the file. BMPRead now returns one of 5 numbers that indicate
the status of the file read 0 means OK, -1 signifies an error opening the
file, -2 means that the file is not a bitmap, -3 means that the bitmap
is not 24-bit RGB, and -4 means that the bitmap is compressed (can't process).
It is up to the program or interface that calls BMPRead() to decide how
to interpret the return data. I decided that it was not wise to have Windows
message boxes being created inside the image editing class, since that
will detract from portability. My new method is much more elegant. I also
took all the code that is used to find the starting points on a window
at which to plot a bitmap and wrapped them into two functions: BMPGetStartX(LONG)
and BMPGetStartY(LONG). Cleans up the source code nicely. On Wed. I will
begin breaking up the program into more separate files....
Wednesday, April 17:
tonight
I began breaking up my program so that it is contained in no less than
7 separate files (not counting menu.rc and resource.h). Dr. McVey says
that this is good for readability, portability, and speeds compile time.
I managed to do it "almost" right the first time, but still have two errors
in wingdi.h that seem to have nothing to do with my code. I'll talk to
McVey tomorrow, should be no big deal
Thursday, April 18:
Dr.
McVey said my problem lied in my use of a constant called BITMAP that holds
the integer 19778. It is used to check if a file being read is indeed a
bitmap. So, I changed the name of the variable. After fixing
some access-related problems, the program worked again. The access
problems were related to the image object NOT being able to be defined
as a global. I had to "get" it from CMainWindow if, say, I needed access
to it inside a dialog box.
Friday, April 19:
Today
marks the last of my tinkering with this program <sniff....>.
Next week shall be devoted entirely to gearing up for the presentation,
fixing this blasted website, and polishing up on public speaking skills.
Today I changed the structure of the ScanLineIndex so that it is an array
of Windows COLORREF variables, instead of PixelRGB class objects.
This is clearly more efficient storage-wise, since I can extract individual
RGB values from COLORREF variables at will. Why would I need to actually
store every pixel component in an array? I also changed all the editing
functions so that the class PixelRGB is now no longer needed. I may
be hallucinating, but the program may be running visibly faster as a result
of the changes!
Week 14: April 22- April 28
Monday, April 22:
Tonight I started commenting all of the source code. Got most of it done
Tuesday, April 23:
Continued with the commenting
Wednesday, April 24:
Did last minute testing; all is well. Also wrote the Presentation document and will hand it in to profs tomorrow as planned.
Friday, April 26:
Finsihed commenting code. Got a list of topics to make visual materials about for the Q&A Session....
Saturday, April 27:
Updated all documentation. Cleaned up this website. Loaded all applicable files to the project. Also getting slides and visuals ready, hopefully going to write up my speech tonight, if not, I will practice a little with the equip. in Cofrin, make sure everything works. (No reason why it shouldn't....)
Sunday, April 28:
Continued to prepare materials for presentation. Wrote out the first 10 minutes. Practiced the opening monologue and my demonstration sequence twice.
Monday, April 29:
The time is at hand..... I prepared the last of the diagrams to make sure they were acceptable and viewable. At 5:30, project was presented. All indications at this time point to a successful defense. A great load is taken off my back....
Sunday, May 5:
Finalized
web page, prepared documents for turning in to DCP. Placed all source
code, user manual, README's, and an .exe version of the program into a
.ZIP package for use on the webpage......
Monday, May 6:
Turn
in all materials relative to the project. Relax.....