Digital image processing <纯c++> reads, crops, scales, rotates, and stores 8-bit BMP grayscale images

Source: Internet
Author: User
Tags bmp image cos fread reserved scale image sin

Original: http://blog.csdn.net/zhengtu009/article/details/17220319


C + + implements the following functions:
1, the realization of the hard disk in the 8-bit BMP image reading and storage;
2, the implementation of the designated rectangular frame area image shearing;
3, the realization of any shape of the image of any proportional scaling;
4, the realization of arbitrary shape of the image of arbitrary angle selection.
Program Editing Environment: Create console Application project in Visual c++6.0, Win32 platform, no MFC, Empty project
Program Operation Instructions:
1, add files Ex1.cpp, Ex1.h
2, compile, run
3, according to the program prompts to complete the operation (note the case of file name)
4, go to the folder, view cutresult.bmp (crop results), scalresult.bmp (Scaling results) and rotresult.bmp (rotation results) file.


Thank you for the following three posts:
http://blog.csdn.net/xiajun07061225/article/details/5813726
http://blog.csdn.net/wangyadong/article/details/3549284
http://blog.csdn.net/xiajun07061225/article/details/6633938
The following code is done with appropriate modifications to the above content.
The header file Ex1.h reads as follows:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef long Long;
bitmap file header definition;
It does not contain file type information (due to the memory structure of the structure,
If added, the file information will not be read correctly.
typedef struct tagbitmapfileheader{
WORD bftype;//file type, must be 0x424d, that is, the character "BM"
DWORD bfsize;//File Size
Word bfreserved1;//reserved word
Word bfreserved2;//reserved word
DWORD bfoffbits;//The number of offset bytes from the file header to the actual bitmap data
}bitmapfileheader;
typedef struct tagbitmapinfoheader{
DWORD bisize;//Information Header size
LONG biwidth;//Image width
LONG biheight;//Image Height
WORD biplanes;//number of bits, must be 1
WORD bibitcount;//number of bits per pixel
DWORD bicompression; Compression type
DWORD biSizeImage; Compressed image size byte count
LONG Bixpelspermeter; Horizontal resolution
LONG Biypelspermeter; Vertical resolution
DWORD biclrused; The number of colors the bitmap actually uses
DWORD biclrimportant; The number of important colors in a standard chart
}bitmapinfoheader; Bitmap Information Header definition
typedef struct tagrgbquad{
BYTE Rgbblue; The blue component of the color
BYTE Rgbgreen; The green component of the color
BYTE rgbred; The red component of the color
BYTE rgbreserved; Reserved value
}rgbquad;//Palette Definition
Pixel information
typedef struct TAGIMAGEDATA
{
BYTE BLUE;///8 Gray-scale image with 1 of them
BYTE Green;
BYTE Red;
}imagedata;
The source file Ex1.cpp contents are as follows:
Ex1.cpp:Defines the entry point for the console application.
//
#include <stdio.h>
#include "Ex1.h"
#include "Stdlib.h"
#include "math.h"
#include <iostream>
#define PI 3.14159//PI macro definition
#define LENGTH_NAME_BMP 30//bmp The maximum length of a picture file name
using namespace Std;
Variable definition
Bitmapfileheader Strhead; Bitmap file Headers
Rgbquad strpla[256];//256 color Palette
Bitmapinfoheader Strinfo;
Display bitmap file header information
void Showbmphead (Bitmapfileheader pbmphead)
{
cout<< "read bitmap file information:" <<endl;
cout<< "File size:" <<pBmpHead.bfSize<<endl;
cout<< "reserved word _1:" <<pBmpHead.bfReserved1<<endl;
cout<< "reserved word _2:" <<pBmpHead.bfReserved2<<endl;
cout<< "The number of offset bytes of actual bitmap data:" <<pBmpHead.bfOffBits<<endl;
}
void Showbmpinforhead (Tagbitmapinfoheader pbmpinforhead)
{
cout<< "read Bitmap information header:" <<endl;
cout<< "Length of structure:" <<pBmpInforHead.biSize<<endl;
cout<< "Bitmap width:" <<pBmpInforHead.biWidth<<endl;
cout<< "Bitmap Height:" <<pBmpInforHead.biHeight<<endl;
cout<< "biplanes plane number:" <<pBmpInforHead.biPlanes<<endl;
cout<< "biBitCount using the number of color digits:" <<pBmpInforHead.biBitCount<<endl;
cout<< "compression mode:" <<pBmpInforHead.biCompression<<endl;
cout<< "bisizeimage the number of bytes in the actual bitmap data:" <<pBmpInforHead.biSizeImage<<endl;
cout<< "x-directional resolution:" <<pBmpInforHead.biXPelsPerMeter<<endl;
cout<< "Y-directional resolution:" <<pBmpInforHead.biYPelsPerMeter<<endl;
cout<< "Number of colors used:" <<pBmpInforHead.biClrUsed<<endl;
cout<< "Important colors:" <<pBmpInforHead.biClrImportant<<endl<<endl;
}
int max (int i,int j)
{
if (I&GT;=J)
return i;
Else
Return J;
}
int main ()
{
Char Strfile[length_name_bmp]; BMP filename
WORD bftype_w=0x4d42;
ImageData *imagedata = NULL; Dynamically allocating a two-dimensional array of pixel information for storing the original picture
ImageData *imagedatacut = null;//Dynamic allocation of a two-dimensional array of pixel information that stores cropped pictures
ImageData *imagedatascal = null;//Dynamic allocation of a two-dimensional array of pixel information for a scaled picture
ImageData *imagedatarot = null;//dynamically allocates a two-dimensional array of pixel information for a rotated picture
int width,height;//picture width and height
float expscalvalue=0; Expected scaling multiples (allowed decimals)
int floattointwidth,floattointheight;/////decimal into integer (float to Int)
int rotateangle=90;//the angle to zoom, default 90
cout<< "Please enter the file name (w.bmp or 06.bmp or 07.bmp) you want to read:" <<endl;
cin>>strfile;
FILE *fpi,*fpw;
Fpi=fopen (strfile, "RB");
if (FPI!= NULL)
{
Read file type First
WORD Bftype;
Fread (&bftype,1,sizeof (WORD), FPI);
if (0x4d42!=bftype)///if!=bmp
{
cout<< "The file is not a BMP file!" <<endl;
return NULL;
}
The file read from printf (\ n) is%s. \ n ', strfile);
Read file headers and headers for BMP files
Fread (&strhead,1,sizeof (Tagbitmapfileheader), FPI);
Showbmphead (Strhead)//Display file headers
Fread (&strinfo,1,sizeof (Tagbitmapinfoheader), FPI);
Showbmpinforhead (Strinfo)//Display file information header
Read Palette
for (unsigned int ncounti=0;ncounti<strinfo.biclrused;ncounti++)
{
Fread (char *) & (Strpla[ncounti].rgbblue), 1,sizeof (BYTE), FPI);
Fread (char *) & (Strpla[ncounti].rgbgreen), 1,sizeof (BYTE), FPI);
Fread (char *) & (strpla[ncounti].rgbred), 1,sizeof (BYTE), FPI);
Fread (char *) & (strpla[ncounti].rgbreserved), 1,sizeof (BYTE), FPI);
}
}
Else
{
cout<< "File Open error!" <<endl;
return NULL;
}
width = strinfo.biwidth;
Height = strinfo.biheight;
ImageData = (imagedata*) malloc (width * height * sizeof (IMAGEDATA))///Allocate storage space for original image
Initializes an array of pixels for the original picture
for (int i = 0;i < Height;++i)
{
for (int j = 0;j < Width;++j)
{
(* (ImageData + i * width + j)). Blue = 0;
(* (ImageData + i * width + j)). Green = 0;
(* (ImageData + i * width + j)). Red = 0;
}
}
Read the pixel data of a picture the row of the number of Read heights at a time
Fread (imagedata,sizeof (struct tagimagedata) * WIDTH,HEIGHT,FPI);/////size_t fread (void *buffer, size_t size, size_t Count, FILE *stream);
Fclose (FPI);
===== Picture Clipping processing ======//////////
int leftdownx,leftdowny,rightupx,rightupy;/////User Input value
int rleftdownx,rleftdowny,rrightupx,rrightupy;/////converted to actual use of numeric values
cout<< enter the coordinates of the lower-left and upper-right corners of the rectangular area you want to crop (four consecutive integer values, such as a): "<<endl;
cin>>leftdownx;
cin>>leftdowny;
cin>>rightupx;
cin>>rightupy;
if (leftdownx<=0| | leftdowny<=0)////Limit the user-entered rectangle to the original image
{
rleftdownx=0;
rleftdowny=0;
}
Else
{
Rleftdownx=leftdownx;
Rleftdowny=leftdowny;
}
if (rightupx>=width)
{
Rrightupx=width;
}
Else
{
RRIGHTUPX=RIGHTUPX;
}
if (rightupy>=height)
{
Rrightupy=height;
}
Else
{
Rrightupy=rightupy;
}
int cutwidth=rrightupx-rleftdownx;
The number of bytes per line of an image must be an integer multiple of 4
Cutwidth = (cutwidth * sizeof (ImageData) + 3)/4 * 4;////The actual width of the rectangular frame
int cutheight=rrightupy-rleftdowny;////Rectangle Frame Actual height
Imagedatacut = (imagedata*) malloc (cutwidth * cutheight * sizeof (ImageData));///Allocate storage space for cropped images
Initialize the pixel array of the cropped picture after a byte-by-word write
for (i = 1;i < cutheight; ++i)
{
for (int j = 0;j < Cutwidth; ++j)
{
(* (Imagedatacut + i * cutwidth + j)). Blue = 0;
}
}
imagedata+= (Rleftdowny) *width+rleftdownx;////The original image data array pointer moves to the lower-left corner of the rectangle box.
for (int k = 0;k < Cutheight;++k)////clipping area data extraction
{
for (int l = 0;l < cutwidth;++l)
* (Imagedatacut + k * cutwidth + L) = * (imagedata+ k * width + L + rleftdownx);////This formula must pay attention to the wording. The main point is to note the use of two-dimensional array pointers.
}
Save a BMP picture
if ((Fpw=fopen ("Cutresult.bmp", "WB")) ==null)
{
cout<< "Create the BMP file error!" <<endl;
return NULL;
}
Fwrite (&bftype_w,1,sizeof (WORD), FPW);
Fwrite (&strhead,1,sizeof (Tagbitmapfileheader), FPW);
Strinfo.biwidth = Cutwidth;
Strinfo.biheight = Cutheight;
Fwrite (&strinfo,1,sizeof (Tagbitmapinfoheader), FPW);
Save Palette Data
for (unsigned int ncounti=0;ncounti<strinfo.biclrused;ncounti++)
{
Fwrite (&strpla[ncounti].rgbblue,1,sizeof (BYTE), FPW);
Fwrite (&strpla[ncounti].rgbgreen,1,sizeof (BYTE), FPW);
Fwrite (&strpla[ncounti].rgbred,1,sizeof (BYTE), FPW);
Fwrite (&strpla[ncounti].rgbreserved,1,sizeof (BYTE), FPW);
}
Save pixel data
for (I =0;i < cutheight;++i)
{
for (int j = 0;j < Cutwidth;++j)
{
Fwrite (& (* (Imagedatacut + i * cutwidth + j)). Blue), 1,sizeof (BYTE), FPW);
Fwrite (& (* (Imagedatarot + i * floattointwidth + j)), Green), 1,sizeof (BYTE), FPW);
Fwrite (& (* (Imagedatarot + i * floattointwidth + j)). Red), 1,sizeof (BYTE), FPW);
}
}
printf (The crop transformation is complete, check the Cutresult.bmp file.) \ n ');
Fclose (FPW);
Free memory
Delete[] imagedata;///cannot release ImageData, which also has data.
Delete[] Imagedatacut;
=========== picture clipping processing End ======////////
========== Reopen the file ======////////
cout<< "Please enter the file name (cutresult.bmp) to read:" <<endl;
cin>>strfile;
Fpi=fopen (strfile, "RB");
if (FPI!= NULL)
{
Read file type First
WORD Bftype;
Fread (&bftype,1,sizeof (WORD), FPI);
if (0x4d42!=bftype)///if!=bmp
{
cout<< "The file is not a BMP file!" <<endl;
return NULL;
}
The file read from printf (\ n) is%s. \ n ', strfile);
Read file headers and headers for BMP files
Fread (&strhead,1,sizeof (Tagbitmapfileheader), FPI);
Showbmphead (Strhead)//Display file headers
Fread (&strinfo,1,sizeof (Tagbitmapinfoheader), FPI);
Showbmpinforhead (Strinfo)//Display file information header
Read Palette
for (unsigned int ncounti=0;ncounti<strinfo.biclrused;ncounti++)
{
Fread (char *) & (Strpla[ncounti].rgbblue), 1,sizeof (BYTE), FPI);
Fread (char *) & (Strpla[ncounti].rgbgreen), 1,sizeof (BYTE), FPI);
Fread (char *) & (strpla[ncounti].rgbred), 1,sizeof (BYTE), FPI);
Fread (char *) & (strpla[ncounti].rgbreserved), 1,sizeof (BYTE), FPI);
}
width = strinfo.biwidth;
Height = strinfo.biheight;
ImageData = (imagedata*) malloc (width * height * sizeof (IMAGEDATA))///Allocate storage space for original image
Initializes an array of pixels for the original picture
for (int i = 0;i < Height;++i)
{
for (int j = 0;j < Width;++j)
{
(* (ImageData + i * width + j)). Blue = 0;
(* (ImageData + i * width + j)). Green = 0;
(* (ImageData + i * width + j)). Red = 0;
}
}
Read the pixel data of a picture the row of the number of Read heights at a time
Fread (imagedata,sizeof (struct tagimagedata) * WIDTH,HEIGHT,FPI);/////
Fclose (FPI);
}
Else
{
cout<< "File Open error!" <<endl;
return NULL;
}
Picture scaling Processing
cout<< "Please enter a multiple to scale:" <<endl;
cin>>expscalvalue;
If Expscalvalue contains decimals, it needs to be integer
Rounding the desired scaling result
floattointwidth= (int) (expscalvalue*width);
floattointheight= (int) (expscalvalue*height);
The number of bytes per line of an image must be an integer multiple of 4
Floattointwidth = (floattointwidth * sizeof (ImageData) + 3)/4 * 4;
Imagedatascal = (imagedata*) malloc (floattointwidth * floattointheight * sizeof (ImageData));///Allocate storage space after zooming
Initialize a pixel array of images after zooming a byte-by-word write
for (i = 1;i < floattointheight; ++i)
{
for (int j = 0;j < Floattointwidth; ++j)
{
(* (imagedatascal + i * floattointwidth + j)). Blue = 0;
(* (Imagedatarot + i * floattointwidth + j)). Green = 0;
(* (Imagedatarot + i * floattointwidth + j)). Red = 0;
}
}
int pre_i,pre_j,after_i,after_j;//pixel coordinates before and after scaling
for (I=0;i<floattointheight;++i)
{
for (int j=0;j<floattointwidth;++j)
{
After_i=i;
After_j=j;
pre_i = (int) (after_i/expscalvalue);/////rounding, interpolation method: Nearest proximity interpolation (nearest neighbor sampling method)
Pre_j = (int) (after_j/expscalvalue);
if (pre_i >= 0 && pre_i < height && pre_j >= 0 && pre_j < width)//in the original scope
* (imagedatascal + i * floattointwidth + j) = * (ImageData + pre_i * width + pre_j);
}
}
Save a BMP picture
if ((Fpw=fopen ("Scalresult.bmp", "WB")) ==null)
{
cout<< "Create the BMP file error!" <<endl;
return NULL;
}
Fwrite (&bftype_w,1,sizeof (WORD), FPW);
Fwrite (&strhead,1,sizeof (Tagbitmapfileheader), FPW);
Strinfo.biwidth = Floattointwidth;
Strinfo.biheight = Floattointheight;
Fwrite (&strinfo,1,sizeof (Tagbitmapinfoheader), FPW);
Save Palette Data
for (ncounti=0;ncounti<strinfo.biclrused;ncounti++)
{
Fwrite (&strpla[ncounti].rgbblue,1,sizeof (BYTE), FPW);
Fwrite (&strpla[ncounti].rgbgreen,1,sizeof (BYTE), FPW);
Fwrite (&strpla[ncounti].rgbred,1,sizeof (BYTE), FPW);
Fwrite (&strpla[ncounti].rgbreserved,1,sizeof (BYTE), FPW);
}
Save pixel data
for (I =0;i < floattointheight;++i)
{
for (int j = 0;j < Floattointwidth;++j)
{
Fwrite (& (* (imagedatascal + i * floattointwidth + j)). Blue), 1,sizeof (BYTE), FPW);
Fwrite (& (* (Imagedatarot + i * floattointwidth + j)), Green), 1,sizeof (BYTE), FPW);
Fwrite (& (* (Imagedatarot + i * floattointwidth + j)). Red), 1,sizeof (BYTE), FPW);
}
}
printf ("Zoom transformation complete, check the scalresult.bmp file.") \ n ');
Fclose (FPW);
Free memory
Delete[] ImageData;
Delete[] imagedatascal;
============== image scaling processing End ==============///////
=============== Image Rotation Processing ====================///////
cout<< "Please enter the file name (scalresult.bmp) to read:" <<endl;
cin>>strfile;
FILE *fror,*frow;
int anyx=0;////A long width adjustment parameter to fit any shape
Fror=fopen (strfile, "RB");
if (fror!= NULL) {
Read file type First
WORD Bftype;
Fread (&bftype,1,sizeof (WORD), fror);
if (0x4d42!=bftype)
{
cout<< "The file is not a BMP file!" <<endl;
return NULL;
}
The file read from printf (\ n) is%s. \ n ', strfile);
Read file headers and headers for BMP files
Fread (&strhead,1,sizeof (Tagbitmapfileheader), fror);
Showbmphead (Strhead)//Display file headers
Fread (&strinfo,1,sizeof (Tagbitmapinfoheader), fror);
Showbmpinforhead (Strinfo)//Display file information header
Read Palette
for (unsigned int ncounti=0;ncounti<strinfo.biclrused;ncounti++)
{
Fread (char *) & (Strpla[ncounti].rgbblue), 1,sizeof (BYTE), fror);
Fread (char *) & (Strpla[ncounti].rgbgreen), 1,sizeof (BYTE), fror);
Fread (char *) & (strpla[ncounti].rgbred), 1,sizeof (BYTE), fror);
Fread (char *) & (strpla[ncounti].rgbreserved), 1,sizeof (BYTE), fror);
}
width = strinfo.biwidth;
Height = strinfo.biheight;
Anyx=max (width,height);///suitable for any shape graphics
The number of bytes per line of an image must be an integer multiple of 4
width = (Width * sizeof (ImageData) + 3)/4 * 4;
ImageData = (imagedata*) malloc (width * height * sizeof (imagedata));
ImageData = (imagedata*) malloc (width * height);
Imagedatarot = (imagedata*) malloc (2 * Width * 2 * height * sizeof (imagedata));
Imagedatarot = (imagedata*) malloc (2 * Anyx * 2 * anyx * sizeof (ImageData));
Initializes an array of pixels for the original picture
for (int i = 0;i < Height;++i)
{
for (int j = 0;j < Width;++j)
{
(* (ImageData + i * width + j)). Blue = 0;
(* (ImageData + i * width + j)). Green = 0;
(* (ImageData + i * width + j)). Red = 0;
}
}
Initializes an array of pixels for a rotated picture
for (i = 0;i < 2 * height;++i)
for (i = 0;i < 2 * anyx;++i)
{
for (int j = 0;j < 2 * anyx;++j)
{
(* (Imagedatarot + i * 2 * Anyx + j)). Blue = 0;
(* (Imagedatarot + i * 2 * width + j)). Green = 0;
(* (Imagedatarot + i * 2 * width + j)). Red = 0;
}
}
Read the pixel data of a picture
Fread (imagedata,sizeof (struct tagimagedata) * width,height,fror);
Fclose (Fror);
}
Else
{
cout<< "File Open error!" <<endl;
return NULL;
}
Picture rotation processing
Double angle;//the number of radians to rotate
int midx_pre,midy_pre,midx_aft,midy_aft;//The coordinates of the center point around which the rotation
Midx_pre = WIDTH/2;
Midy_pre = HEIGHT/2;
Midx_aft = Anyx;
Midy_aft = Anyx;
cout<< "Please enter the angle to rotate (0 degrees to 360 degrees, counterclockwise rotation):" <<endl;
cin>>rotateangle;
Angle = 1.0 * Rotateangle * PI/180;
/* Geometric formula for image rotation
X2=x1*cos (θ2)-y1*sin (θ2);
Y2=x1*sin (θ2) +y1*cos (θ2);
*/
for (i = 0;i < 2 * height;++i)
for (i = 0;i < 2 * anyx;++i)
{
for (int j = 0;j < 2 * anyx;++j)
{
After_i = i-midx_aft;//coordinate transformation, if the coordinates are not transformed, the picture will be turned out of the coordinates when rotated (0,0) as the reference point.
After_j = J-midy_aft;
pre_i = (int) (COS ((double) angle) * After_i-sin (double) angle) * After_j) + midx_pre; The interpolation method is: Nearest proximity interpolation (nearest neighbor sampling method)
Pre_j = (int) (sin (double) angle) * after_i + cos ((double) angle) * After_j) + midy_pre;
/*after_i = i;
After_j = j; Coordinate does not transform
pre_i = (int) (COS ((double) angle) * After_i-sin (double) angle) * After_j);
Pre_j = (int) (sin (double) angle) * after_i + cos ((double) angle) * after_j); */////coordinate does not transform effect
if (pre_i >= 0 && pre_i < height && pre_j >= 0 && pre_j < width)//in the original scope
* (Imagedatarot + i * 2 * Anyx + j) = * (ImageData + pre_i * Anyx + pre_j);
}
}
Save a BMP picture
if ((Frow=fopen ("Rotresult.bmp", "WB")) ==null)
{
cout<< "Create the BMP file error!" <<endl;
return NULL;
}
bftype_w=0x4d42;
Fwrite (&bftype_w,1,sizeof (WORD), frow);//frow automatic +=2;
Fwrite (&strhead,1,sizeof (Tagbitmapfileheader), frow);
Strinfo.biwidth = 2 * anyx;//width;
Strinfo.biheight = 2 * anyx;//height;
Fwrite (&strinfo,1,sizeof (Tagbitmapinfoheader), frow);
Save Palette Data
for (ncounti=0;ncounti<strinfo.biclrused;ncounti++)
{
Fwrite (&strpla[ncounti].rgbblue,1,sizeof (BYTE), frow);
Fwrite (&strpla[ncounti].rgbgreen,1,sizeof (BYTE), frow);
Fwrite (&strpla[ncounti].rgbred,1,sizeof (BYTE), frow);
Fwrite (&strpla[ncounti].rgbreserved,1,sizeof (BYTE), frow);
}
Save pixel data
for (I =0;i < 2 * anyx;++i)
{
for (int j = 0;j < 2 * width;++j)
for (int j = 0;j < 2 * anyx;++j)
{
Fwrite (& (* (Imagedatarot + i * 2 * Anyx + j)). Blue), 1,sizeof (BYTE), frow);
Fwrite (& (* (Imagedatarot + i * 2 * width + j)), Green), 1,sizeof (BYTE), FPW);
Fwrite (& (* (Imagedatarot + i * 2 * width + j)). Red), 1,sizeof (BYTE), FPW);
}
}
printf ("Rotate transformation complete, check the rotresult.bmp file.") \ n ');
Fclose (FROW);
Free memory
Delete[] ImageData;
Delete[] Imagedatarot;
================== image rotation processing end ============///////////
return 1;
}
/*
Program to use the picture from Google Pictures can be found, as long as the 8-bit BMP bitmap can be. Change the name to 06.bmp, 07.bmp, or w.bmp
*/


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.