//FILE: BMPEdit24.cpp //Implementation of the image editor BMPImage class #define FILECHECK 19778 //Integer marks file as BITMAP #include //for file I/O #include //for standard input/output #include "ImgEditJob_ids.h" //for image editing function IDs #include "BMPEdit24.h" //declarations for BMPImage class #include "CMainWindow.h" //declarations for CMainWindow class #include //Application Frameworks Header /********************************************************************** Member functions for BMPImage class **********************************************************************/ BMPImage::BMPImage(){ //constructor } BMPImage::~BMPImage(){ //destructor } int BMPImage::BMPRead(char ImgFile[80]){ /********************************************************************** This function reads data from a 24-bit RGB bitmap file and stores it in a BMPImage object. Input: Filename of bitmap file Output: Image data to file header and image data structures Return: 0 == File read successful -1 == Error opening File -2 == File is NOT a bitmap -3 == File is NOT 24-bit RGB -4 == image data is COMPRESSED Image data is read into the BMPImage bitmap data structures Any errors in reading the file, as indicated by the return data, are handled by the caller of BMPRead() ***********************************************************************/ fstream df; // filestream variable int i, j; // index variables.... BYTE pixel_r, pixel_g, pixel_b; //RGB color component variables //open file..... df.open(ImgFile, ios::in | ios::binary); //if file cannot be opened if (!df) { return -1; } //File is opened. Start reading data //Read the file header.... df.read( (char *)&fhType, sizeof(short)); df.read( (char *)&fhSize, sizeof(DWORD)); df.read( (char *)&fhReserved1, sizeof(short)); df.read( (char *)&fhReserved2, sizeof(short)); df.read( (char *)&fhOffBits, sizeof(DWORD)); //Check for valid file type if (fhType != FILECHECK){ return -2; } //Read the info header.... df.read( (char *)&ihSize, sizeof(DWORD)); df.read( (char *)&ihWidth, sizeof(LONG)); df.read( (char *)&ihHeight, sizeof(LONG)); df.read( (char *)&ihPlanes, sizeof(WORD)); df.read( (char *)&ihBitCount, sizeof(WORD)); df.read( (char *)&ihCompression, sizeof(DWORD)); df.read( (char *)&ihSizeImage, sizeof(DWORD)); df.read( (char *)&ihXPelsPerMeter, sizeof(LONG)); df.read( (char *)&ihYPelsPerMeter, sizeof(LONG)); df.read( (char *)&ihClrUsed, sizeof(DWORD)); df.read( (char *)&ihClrImportant, sizeof(DWORD)); //Make sure bitmap is 24-bit RGB and NOT compressed..... if (ihBitCount != 24){ return -3; } if (ihCompression > 0){ return -4; } //Set the size of the image pixel array based upon the height and width //of the bitmap ScanLineIndex.SetSize(ihHeight); for( i=0; iMessageBox( "Cannot open file for writing", "File Error", MB_OK); return; } //write the fileheader of the image... outf.write((char *)&fhType, sizeof(short)); outf.write((char *)&fhSize, sizeof(DWORD)); outf.write( (char *)&fhReserved1, sizeof(short)); outf.write( (char *)&fhReserved2, sizeof(short)); outf.write( (char *)&fhOffBits, sizeof(DWORD)); // write the info header of the image.... outf.write( (char *)&ihSize, sizeof(DWORD)); outf.write( (char *)&ihWidth, sizeof(LONG)); outf.write( (char *)&ihHeight, sizeof(LONG)); outf.write( (char *)&ihPlanes, sizeof(WORD)); outf.write( (char *)&ihBitCount, sizeof(WORD)); outf.write( (char *)&ihCompression, sizeof(DWORD)); outf.write( (char *)&ihSizeImage, sizeof(DWORD)); outf.write( (char *)&ihXPelsPerMeter, sizeof(LONG)); outf.write( (char *)&ihYPelsPerMeter, sizeof(LONG)); outf.write( (char *)&ihClrUsed, sizeof(DWORD)); outf.write( (char *)&ihClrImportant, sizeof(DWORD)); //write the bitmap pixel data.... for( i=0; iGetPixel(j, i); //Get current image data from temp_dc //extract color component data from cref pixel_r = GetRValue(cref); pixel_g = GetGValue(cref); pixel_b = GetBValue(cref); //Write each pixel component in succession. //Order must be b-g-r!!!! (as per Windows Bitmap structure) outf.write((char *)&pixel_b, sizeof(BYTE)); outf.write((char *)&pixel_g, sizeof(BYTE)); outf.write((char *)&pixel_r, sizeof(BYTE)); } } outf.close(); //close the file EDIT_FUNCTION = -1; //reset flag return; } void BMPImage::BMPRedraw(CDC * dc){ /********************************************************************** This function draws image pixels onto the specified Windows Device Context using pixel data contained in the temporary DC (temp_dc). This function is typically called whenever image data is altered, or when a window must be refreshed. Parameters: CDC * dc -- pointer to DC on which to draw the image Input: pixels stored on the device contex in memory temp_dc Output: Pixels are drawn on the specified DC pointed to by CDC * dc Return: None. ***********************************************************************/ int i, j; int xStartAt, yStartAt; // coordinates at which to start plotting the bitmap // Find the coordinates at which to start plotting the bitmap xStartAt = BMPGetStartX(ihWidth);//abs((ihWidth/2) - xCenter); yStartAt = BMPGetStartY(ihHeight);//(ihHeight/2) + yCenter; // Copy the pixel data from temp_dc to dc for(i=0; iSetPixel(j+xStartAt, yStartAt-i, temp_dc->GetPixel(j, i)); } } EDIT_FUNCTION = -1; //reset flag to neutral value return; } void BMPImage::BMPDraw(CDC * dc){ /********************************************************************** This function draws image pixels onto the specified Windows Device Context using pixel data contained in a BMPImage object's ScanLineArray. This function is typically used for initial drawings and for restoring an image to its original appearance Parameters: CDC * dc -- pointer to the DC on which to draw the image Input: pixel data in the form of type COLORREF from ScanLineIndex Output: Pixels are drawn on the specified DC pointed to by CDC * dc Return: None. ***********************************************************************/ int xStartAt, yStartAt; // Find the coordinates at which to start plotting the bitmap ihWidth = OrigWidth; ihHeight = OrigHeight; //Reset height and width to original values xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); // Draw bitmap image // NOTE: starting at bottom of bitmap CBitmap bmp; //An empty Windows bitmap bmp.CreateCompatibleBitmap(dc, ihWidth, ihHeight); //create bitmap compatible with DC temp_dc->SelectObject(&bmp); //place empty bitmap on DC //Draw pixels on dc and temp_dc for (int i = (ihHeight-1); i > 0; i--){ for(int j = 0; jSetPixel(j+xStartAt, yStartAt-i, ScanLineIndex[i][j]); temp_dc->SetPixel(j, i, ScanLineIndex[i][j]); } } EDIT_FUNCTION = -1; // reset flag to neutral value return; } void BMPImage::BMPCopyDC(CDC * s_dc, CDC * d_dc) { /********************************************************************** This function copies the pixels from one DC to another DC. The source and destination DC's must have empty CBitmap objects of equal dimensions selected into them. Parameters: CDC * s_dc -- Source DC CDC * d_dc -- Destination DC Input: Pixels from s_dc Output: Pixels are drawn on d_dc Return: None. ***********************************************************************/ int i, j; //index variables //Copy the pixels from the source to the destination for (i=0; iSetPixel(j,i, s_dc->GetPixel(j,i)); } } return; } void BMPImage::BMPBrightnessUp(CDC * dc) { /********************************************************************** This function increaes the color component values of each pixel in order to increase the brightness of an image. Parameters: CDC * dc -- pointer to Windows device context Input: Pixels from temp_dc Output: Pixels are drawn on DC pointed to by CDC * dc Return: None. ***********************************************************************/ int i, j; //index variables int xStartAt, yStartAt; //start coordinates for drawing image BYTE pixel_r, pixel_g, pixel_b; //RGB color components COLORREF cref; //Long integer containing RGB data // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); for(i=0; iGetPixel(j, i); //get pixel from current image pixel_b = GetBValue(cref); //extract RGB components pixel_g = GetGValue(cref); pixel_r = GetRValue(cref); //scale pixel components upward, if ther is no danger of wrapping the //integers if (pixel_r < 245) pixel_r += 10; if (pixel_g < 245) pixel_g += 10; if (pixel_b < 245) pixel_b += 10; //redraw the pixel on the temp_dc and dc (back to screen) cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; //reset flag to neutral value return; } void BMPImage::BMPBrightnessDown(CDC * dc) { /********************************************************************** This function decreaes the color component values of each pixel in order to increase the brightness of an image. Parameters: CDC * dc -- pointer to Windows device context Input: Pixels from temp_dc Output: Pixels are drawn on DC pointed to by CDC * dc and back to temp_dc Return: None. ***********************************************************************/ int i, j; //index variables COLORREF cref; //Long integer containing RGB data BYTE pixel_r, pixel_g, pixel_b; //RGB color components int xStartAt, yStartAt; //Start coordinates for drawing image // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); for(i=0; iGetPixel(j, i); //get pixel from current image pixel_b = GetBValue(cref); //extract RGB components pixel_g = GetGValue(cref); pixel_r = GetRValue(cref); //scale pixel components downward, if ther is no danger of wrapping the //integers if (pixel_r >= 10) pixel_r -= 10; if (pixel_g >= 10) pixel_g -= 10; if (pixel_b >= 10) pixel_b -= 10; //redraw the pixel on the temp_dc and dc (back to screen) cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; //reset flag to neutral value return; } void BMPImage::BMPGrayScale(CDC * dc){ /*************************************************************************** Converts the pixel data in ScanLineIndex to the gray scale (Black & White) by averaging each pixel's RGB values, and replacing the RGB values with the average. Parameters: CDC * dc -- pointer to Windows device context Input: Pixels from temp_dc Output: Pixels are drawn on DC pointed to by CDC * dc and back to temp_dc Return: None. ***************************************************************************/ int i, j; //index variables int RGBsum; //sum of RGB components int avgresult; //result of average COLORREF cref; //Long integer containing RGB data BYTE pixel_r, pixel_g, pixel_b; //RGB color components int xStartAt, yStartAt; //Starting coordinates for drawing the image in the Main Window // Find the coordinates at which to start plotting image.... xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); for(i=0; iGetPixel(j, i); //get pixel from current image pixel_b = GetBValue(cref); //extract RGB components pixel_g = GetGValue(cref); pixel_r = GetRValue(cref); //compute average component value for this pixel RGBsum = (pixel_r + pixel_g + pixel_b ); avgresult = RGBsum / 3; //assign each RGB component the average pixel_r = avgresult; pixel_g = avgresult; pixel_b = avgresult; //redraw the pixel on the temp_dc and dc (back to screen) cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; //reset flag to neutral value return; } void BMPImage::BMPNegative(CDC * dc){ /***************************************************************************** Alters the pixel data in the current image so that the image appears as a negative of the original. Parameters: CDC * dc -- pointer to Windows device context Input: Pixels from temp_dc Output: Pixels are drawn on DC pointed to by CDC * dc and back to temp_dc Return: None. *****************************************************************************/ int i, j; //index variables COLORREF cref; //Long integer containing RGB data BYTE pixel_r, pixel_g, pixel_b; //RGB color component values int xStartAt, yStartAt; //Start coordinates for drawing image in Main Window // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); for (i=0; iGetPixel(j, i); //get pixel from current image pixel_b = GetBValue(cref); //extract RGB components pixel_g = GetGValue(cref); pixel_r = GetRValue(cref); //invert each pixel component pixel_r = 255 - pixel_r; pixel_b = 255 - pixel_b; pixel_g = 255 - pixel_g; //redraw the pixel on temp_dc, and the main window DC (CDC * dc) cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; //reset flag to neutral value return; } void BMPImage::BMPContrastUp(CDC * dc){ /************************************************************************** This function alters the pixel data in ScanLineIndex so that the contrast of the image is increased. Parameters: CDC * dc -- pointer to Windows device context Input: Pixels from temp_dc Output: Pixels are drawn on DC pointed to by CDC * dc and back to temp_dc Return: None. **************************************************************************/ int i, j; //index variables double luminance; //luminance value for ONE pixel double avg_luminance = 0; //average luminance for all pixels COLORREF cref; //Long integer containing RGB data int xStartAt, yStartAt; //Start coordinates for drawing image in Main Window BYTE pixel_r, pixel_g, pixel_b; //RGB color component values // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); // Compute mean luminance value for all pixels // luminance = .30r + .59g + .11b for(i=0; iGetPixel(j, i); pixel_r = GetRValue(cref); pixel_g = GetBValue(cref); pixel_b = GetBValue(cref); luminance = (.30 * pixel_r) + (.59 * pixel_g) + (.11 * pixel_b); avg_luminance = avg_luminance + luminance; } } //calculate the average avg_luminance = avg_luminance / (ihHeight*ihWidth); //now adjust for (i=0; iGetPixel(j, i); pixel_r = GetRValue(cref); pixel_g = GetBValue(cref); pixel_b = GetBValue(cref); luminance = (.30 * pixel_r) + (.59 * pixel_g) + (.11 * pixel_b); if (luminance < avg_luminance){ if (pixel_r >= 10) pixel_r -= 10; if (pixel_g >= 10) pixel_g -= 10; if (pixel_b >= 10) pixel_b -= 10; } if (luminance > avg_luminance){ if (pixel_r < 245) pixel_r += 10; if (pixel_g < 245) pixel_g += 10; if (pixel_b < 245) pixel_b += 10; } cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; return; } void BMPImage::BMPContrastDown(CDC * dc){ /************************************************************************** ** Alters the pixel data in ScanLineIndex so that the contrast of the image ** is increased. **************************************************************************/ int i, j; double luminance; //luminance value for ONE pixel double avg_luminance = 0; COLORREF cref; BYTE pixel_r, pixel_b, pixel_g; int xStartAt, yStartAt; // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); // Compute mean luminance value for all pixels // luminance = .30r + .59g + .11b for(i=0; iGetPixel(j, i); pixel_r = GetRValue(cref); pixel_g = GetBValue(cref); pixel_b = GetBValue(cref); luminance = (.30 * pixel_r) + (.59 * pixel_g) + (.11 * pixel_b); avg_luminance = avg_luminance + luminance; } } avg_luminance = avg_luminance / (ihHeight*ihWidth); for (i=0; iGetPixel(j,i); pixel_r = GetRValue(cref); pixel_g = GetBValue(cref); pixel_b = GetBValue(cref); luminance = (.30 * pixel_r) + (.59 * pixel_g) + (.11 * pixel_b); if (luminance < avg_luminance) { if (pixel_r < 245) pixel_r += 10; if (pixel_g < 245) pixel_g += 10; if (pixel_b < 245) pixel_b += 10; } if (luminance > avg_luminance) { if (pixel_r >= 10) pixel_r -= 10; if (pixel_g >= 10) pixel_g -= 10; if (pixel_b >= 10) pixel_b -= 10; } cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; return; } /********************************************************************** TINT CONTROL FUNCTIONS NOTE: The following six functions are nearly identical in operation, except they alter different color components (Red,green or blue). These functions increase or decrease a given color component to change the appearance of the image so that the given color is more or less pronounced in the image. Parameters: CDC * dc Pointer to a Windows Device Context Input: Pixels from temp_dc Output: Altered pixels redrawn to dc (window's dc) and temp_dc (mem.) Return: None **********************************************************************/ void BMPImage::BMPRedTintUp(CDC * dc){ int i,j; //index variables COLORREF cref;//Long integer containing RGB data BYTE pixel_r, pixel_g, pixel_b; //RGB color component values int xStartAt, yStartAt; //Start coordinates for drawing image in a window // Find the coordinates at which to start // Used for redrawing image on Main Window's DC xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); for (i=0; iGetPixel(j, i); //extract RGB values pixel_r = GetRValue(cref); pixel_g = GetGValue(cref); pixel_b = GetBValue(cref); //increase red component value if (pixel_r < 245) pixel_r += 10; //redraw pixel to temp_dc and Main Window cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; //reset flag to neutral value return; } void BMPImage::BMPRedTintDown(CDC * dc){ //////////////////////////////////////////////// //NOTE: REFER TO FIRST TINT CONTROL FUNCTION FOR //INLINE DOCUMENTATION (COMMENTS) //THIS FUNCTION IS IDENTICAL IN PROCEDURE TO THE FIRST int i, j; COLORREF cref; BYTE pixel_r, pixel_g, pixel_b; int xStartAt, yStartAt; // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); for (i=0; iGetPixel(j, i); pixel_r = GetRValue(cref); pixel_b = GetBValue(cref); pixel_g = GetGValue(cref); // decrease red component value if (pixel_r >= 10) pixel_r -= 10; cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; return; } void BMPImage::BMPGreenTintUp(CDC * dc){ //////////////////////////////////////////////// //NOTE: REFER TO FIRST TINT CONTROL FUNCTION FOR //INLINE DOCUMENTATION (COMMENTS) //THIS FUNCTION IS IDENTICAL IN PROCEDURE TO THE FIRST int i, j; COLORREF cref; BYTE pixel_r, pixel_g, pixel_b; int xStartAt, yStartAt; // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); for (i=0; iGetPixel(j, i); pixel_r = GetRValue(cref); pixel_b = GetBValue(cref); pixel_g = GetGValue(cref); //increase green component value if (pixel_g <= 245) pixel_g += 10; cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; return; } void BMPImage::BMPGreenTintDown(CDC * dc){ //////////////////////////////////////////////// //NOTE: REFER TO FIRST TINT CONTROL FUNCTION FOR //INLINE DOCUMENTATION (COMMENTS) //THIS FUNCTION IS IDENTICAL IN PROCEDURE TO THE FIRST int i, j; COLORREF cref; BYTE pixel_r, pixel_b, pixel_g; int xStartAt, yStartAt; // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); for (i=0; iGetPixel(j, i); pixel_r = GetRValue(cref); pixel_b = GetBValue(cref); pixel_g = GetGValue(cref); //decrease green component value if (pixel_g >= 10) pixel_g -= 10; cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; return; } void BMPImage::BMPBlueTintUp(CDC * dc){ //////////////////////////////////////////////// //NOTE: REFER TO FIRST TINT CONTROL FUNCTION FOR //INLINE DOCUMENTATION (COMMENTS) //THIS FUNCTION IS IDENTICAL IN PROCEDURE TO THE FIRST int i, j; COLORREF cref; BYTE pixel_r, pixel_g, pixel_b; int xStartAt, yStartAt; // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); for (i=0; iGetPixel(j, i); pixel_r = GetRValue(cref); pixel_g = GetGValue(cref); pixel_b = GetBValue(cref); //increae blue color component value if (pixel_b <= 245) pixel_b += 10; cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; return; } void BMPImage::BMPBlueTintDown(CDC * dc){ //////////////////////////////////////////////// //NOTE: REFER TO FIRST TINT CONTROL FUNCTION FOR //INLINE DOCUMENTATION (COMMENTS) //THIS FUNCTION IS IDENTICAL IN PROCEDURE TO THE FIRST int i, j; COLORREF cref; BYTE pixel_r, pixel_g, pixel_b; int xStartAt, yStartAt; // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); for (i=0; iGetPixel(j, i); pixel_r = GetRValue(cref); pixel_g = GetGValue(cref); pixel_b = GetBValue(cref); //decrease blue color component value if (pixel_b >= 10) pixel_b -= 10; cref = RGB(pixel_r, pixel_g, pixel_b); dc->SetPixel(j+xStartAt, yStartAt-i, cref); temp_dc->SetPixel(j, i, cref); } } EDIT_FUNCTION = -1; return; } void BMPImage::BMPRotate90(CDC * dc){ /********************************************************************** This function moves the pixels of an image and redraws them in such a fashion that the redrawn image is rotated 90 degrees to the left Parameters: CDC * dc -- Pointer to Windows Device Context Input: Image pixels from temp_dc Output: Draws rotated image on temp_dc, Main Window's DC Return: None **********************************************************************/ int i, j; //index variables LONG Rwidth, Rheight, Temp; //New height and width of bitmap, a temp variable CDC * old_img_dc; //DC to store the original image CBitmap OldBitmap, NewBitmap;// CBitmap objects to transfer image between DC's COLORREF cref; //Long integer containing RGB data int xStartAt, yStartAt; //Start coordinates for image drawing // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); //Create dc, make it compatible with temp_dc old_img_dc = new CDC; old_img_dc->CreateCompatibleDC(temp_dc); //Create new CBitmap, make it compatible with temp_dc dimensions OldBitmap.CreateCompatibleBitmap(temp_dc, ihWidth, ihHeight); //transfer the blank image into old_img_dc old_img_dc->SelectObject(&OldBitmap); //copy image from temp_dc to old_img_dc BMPCopyDC(temp_dc, old_img_dc); //Create new bitmap with dimensions of rotated DC and select it //into temp_dc NewBitmap.CreateCompatibleBitmap(temp_dc, ihHeight, ihWidth); temp_dc->SelectObject(&NewBitmap); Rwidth = 0; Rheight = 0; for(i=0; i0; j--){ //get pixel from original image and //draw it in its rotated coordinates cref = old_img_dc->GetPixel(i,j); temp_dc->SetPixel(Rheight, Rwidth, cref); Rheight++; } Rheight = 0; Rwidth++; } //swap image's dimensions to reflect rotation Temp = ihWidth; ihWidth = ihHeight; ihHeight = Temp; AfxGetMainWnd()->Invalidate(TRUE); //Force repaint of rotated image..... EDIT_FUNCTION = -1; //reset flag to neutral value. return; } void BMPImage::BMPMirror(CDC * dc){ /********************************************************************** This function reverses the position of each pixel so that the image gets inverted, or mirrored, horizontally. Parameters: CDC * dc -- pointer to Windows DC Input: pixels from temp_dc Output: mirror image drawn on temp_dc and the Main Window DC Return: NONE **********************************************************************/ int i, j; //index variables COLORREF cref, cref2; //LONG integers that hold RGB data int xStartAt, yStartAt; //Start coordinates for image drawing // Find the coordinates at which to start xStartAt = BMPGetStartX(ihWidth); yStartAt = BMPGetStartY(ihHeight); // create mirrored image..... for (i=0; iGetPixel(j, i); cref2 = temp_dc->GetPixel((ihWidth-(j+1)), i); //redraw the pixels opposite of their original coordinates dc->SetPixel(j+xStartAt, yStartAt-i, cref2); temp_dc->SetPixel(j, i, cref2); dc->SetPixel((ihWidth-(j+1)+xStartAt), yStartAt-i, cref); temp_dc->SetPixel((ihWidth-(j+1)), i, cref); } } EDIT_FUNCTION = -1; //reset flag to neutral value return; } void BMPImage::BMPZoomIn(CDC * dc){ /********************************************************************** This function magnifies an image by 10% Parameters: CDC * dc -- pointer to Windows DC Input: pixels from temp_dc (copied to another temp) Output: magnified image drawn on temp_dc and the Main Window DC Return: NONE **********************************************************************/ int i, j; //index variables int new_x, new_y; //new positions of pixels on magnified image int XWidth, XHeight; // expanded width and height of zoomed in bitmap CBitmap OldBitmap, NewBitmap; // CBitmap objects to hold image data CDC * old_img_dc; // DC to hold image data temporarily //First calculate width and height of magnified image XWidth = (int)(ihWidth+ihWidth*.1); XHeight = (int)(ihHeight + ihHeight*.1); // Create new DC to hold old image, transfer old image to that DC old_img_dc = new CDC; old_img_dc->CreateCompatibleDC(temp_dc); OldBitmap.CreateCompatibleBitmap(temp_dc, ihWidth, ihHeight); old_img_dc->SelectObject(&OldBitmap); BMPCopyDC(temp_dc, old_img_dc); NewBitmap.CreateCompatibleBitmap(temp_dc, XWidth, XHeight); temp_dc->SelectObject(&NewBitmap); new_x=0; //x-pos on magnified image new_y=0; //y-pos on magnified image for(i=0; iSetPixel(new_x, new_y, old_img_dc->GetPixel(j,i)); if(j%10 == 0){ //every 10th pixel gets drawn twice new_x++; temp_dc->SetPixel(new_x, new_y, old_img_dc->GetPixel(j,i)); } new_x++; } new_x = 0; if (i%10 == 0){//every 10th scanline gets drawn twice new_y++; for(j=0; jSetPixel(new_x, new_y, old_img_dc->GetPixel(j,i)); if(j%10 == 0){//every 10th pixel gets drawn twice new_x++; temp_dc->SetPixel(new_x, new_y, old_img_dc->GetPixel(j,i)); } new_x++; } new_x = 0; } new_y++; } ihWidth = XWidth; ihHeight = XHeight; //set Bitmap width and height values to new values EDIT_FUNCTION = -1; //reset flag to neutral value AfxGetMainWnd()->Invalidate(TRUE); //force redraw of window return; } void BMPImage::BMPZoomOut(CDC * dc){ /********************************************************************** This function reduces an image by 10% Parameters: CDC * dc -- pointer to Windows DC Input: pixels from temp_dc (copied to another temp) Output: reduced image drawn on temp_dc and the Main Window DC Return: NONE **********************************************************************/ int i, j; //index variables int new_x, new_y; //new postions of pixels on reduced image int XWidth, XHeight; //new width and height of reduced bitmap CBitmap OldBitmap, NewBitmap; //CBitmap objects to hold image data CDC * old_img_dc; //DC to temporarily hold image //Find height and width of reduced bitmap XWidth = (int)(ihWidth-ihWidth*.1); XHeight = (int)(ihHeight - ihHeight*.1); //Create new DC to hold old image and move image into it old_img_dc = new CDC; old_img_dc->CreateCompatibleDC(temp_dc); OldBitmap.CreateCompatibleBitmap(temp_dc, ihWidth, ihHeight); old_img_dc->SelectObject(&OldBitmap); BMPCopyDC(temp_dc, old_img_dc); NewBitmap.CreateCompatibleBitmap(temp_dc, XWidth, XHeight); temp_dc->SelectObject(&NewBitmap); new_x=0; new_y=0; for(i=0; iSetPixel(j, i, old_img_dc->GetPixel(new_x,new_y)); if(j%10 == 0){//Skip every 10th pixel new_x++; } new_x++; } new_x = 0; if (i%10 == 0){//Skip every 10th scan line new_y++; } new_y++; } AfxGetMainWnd()->Invalidate(TRUE); //Repaint window, draw image.... ihWidth = XWidth; //update bitmap dimensions ihHeight = XHeight; EDIT_FUNCTION = -1; // set flag to neutral value return; } /******************************************************************************** ********* NON-EDITING Functions --- These methods do not edit the image, but ********* retrieve data, calculate important values, etc.....******************** ********************************************************************************/ LONG BMPImage::GetBMPWidth(){ // Returns bitmap width return ihWidth; } LONG BMPImage::GetBMPHeight(){ //returns bitmap height. return ihHeight; } int BMPImage::BMPGetStartX(LONG xwidth){ /********************************************************************************************** ******** Uses info from the Main Window to calculate the appropriate x-axis starting position ******** at which to plot the image.......*****************************************************/ RECT rr; // RECT object to hold Main Window data int xmax; int xCenter; // Center x-coordinate for CMainWindow // Find the CENTER coordinates of the Main Window.... AfxGetMainWnd()->GetClientRect(&rr); // get Main Window data xmax = rr.right; xCenter = xmax / 2; // Find the x-coordinate at which to start plotting the bitmap return (abs((xwidth/2) - xCenter)); // return the answer..... } int BMPImage::BMPGetStartY(LONG yheight){ /********************************************************************************************** ******** Uses info from the Main Window to calculate the appropriate y-axis starting position ******** at which to plot the image.......*****************************************************/ RECT rr; // RECT object to hold Main Window data int ymax; int yCenter; // Center y-coordinate for CMainWindow // Find the CENTER coordinates of the Main Window.... AfxGetMainWnd()->GetClientRect(&rr); // get Main Window data ymax = rr.bottom; yCenter = ymax / 2; // Find the y-coordinate at which to start plotting the bitmap return ((ihHeight/2) + yCenter); } /////////BMPEdit24.cpp