Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //*************************************************************
- //*
- //* Обрезать
- //*
- //*************************************************************
- void Cut(LPHICOLOR * pImageData, LPDWORD pWidth, LPDWORD pHeight, DWORD left, DWORD top, DWORD right, DWORD bottom)
- {
- //****
- LPHICOLOR pNewImageData;
- DWORD ImageOffset;
- DWORD NewImageOffset;
- DWORD x;
- DWORD y;
- DWORD width;
- DWORD height;
- // расчитываем новый размер
- width = right - left + 1;
- height = bottom - top + 1;
- // выделяем память под результирующие рабочие данные изображения
- pNewImageData = (LPHICOLOR)GlobalAlloc(GPTR,width*height*sizeof(HICOLOR));
- // формируем обрезанное рабочее изображение
- for( y=0; y<height; y++ )
- {
- for( x=0; x<width; x++ )
- {
- // расчитываем смещения
- ImageOffset = (y + top) * (*(pWidth)) + x + left;
- NewImageOffset = y * width + x;
- // формируем рабочие данные
- (pNewImageData+NewImageOffset)->Color = (*(pImageData)+ImageOffset)->Color;
- }
- }
- // освобождаем ранее выделенную память под рабочие данные изображения
- GlobalFree(*(pImageData));
- // и передаем новую
- *(pImageData) = pNewImageData;
- // возвращаем новые размеры
- *(pWidth) = width;
- *(pHeight) = height;
- }
- //*************************************************************
- //*
- //* Изменить размер
- //*
- //*************************************************************
- void Resize(LPHICOLOR * pImageData, LPDWORD pWidth, LPDWORD pHeight, DWORD NewWidth, DWORD NewHeight)
- {
- //****
- LPHICOLOR pNewImageData;
- DWORD ImageOffset;
- DWORD NewImageOffset;
- DWORD X;
- DWORD Y;
- DWORD NewX;
- DWORD NewY;
- DWORD CountX;
- DWORD CountY;
- // выделяем память под результирующие рабочие данные изображения
- pNewImageData = (LPHICOLOR)GlobalAlloc(GPTR,NewWidth*NewHeight*sizeof(HICOLOR));
- // формируем рабочее изображение с новыми размерами
- // Основа этих "хитрых" преобразований корнями уходит в целочисленные методы формирования
- // графических примитивов по Брезенхему, с которыми вы должны быть знакомы, так как прочитали указанную мною книгу...
- for( Y=NewY=0,CountY=0; NewY<NewHeight; NewY++,CountY+=*(pHeight) )
- {
- while( CountY >= NewHeight )
- {
- CountY -= NewHeight;
- Y++;
- }
- for( X=NewX=0,CountX=0; NewX<NewWidth; NewX++,CountX+=*(pWidth) )
- {
- while( CountX >= NewWidth )
- {
- CountX -= NewWidth;
- X++;
- }
- // расчитываем смещения
- ImageOffset = Y * (*(pWidth)) + X;
- NewImageOffset = NewY * NewWidth + NewX;
- // формируем рабочие данные
- (pNewImageData+NewImageOffset)->Color = (*(pImageData)+ImageOffset)->Color;
- }
- }
- // освобождаем ранее выделенную память под рабочие данные изображения
- GlobalFree(*(pImageData));
- // и передаем новую
- *(pImageData) = pNewImageData;
- // возвращаем новые размеры
- *(pWidth) = NewWidth;
- *(pHeight) = NewHeight;
- }
- //*************************************************************
- //*
- //* Добавить шум
- //*
- //*************************************************************
- void AppendNoise(LPHICOLOR pImageData, DWORD width, DWORD height)
- {
- //****
- DWORD ImageOffset;
- DWORD x;
- DWORD y;
- SYSTEMTIME time;
- DWORD Count;
- DWORD Random;
- BYTE gray;
- // инициализируем датчик случайных чисел на основании текущего времени
- GetLocalTime(&time);
- Random = time.wMilliseconds * time.wSecond * time.wMinute * time.wHour;
- // формиуруем шум
- for( Count=0; Count<10000; Count++ )
- {
- // генерируем положение
- Random = Random * 214013 + 2531011;
- x = Random % width;
- Random = Random * 214013 + 2531011;
- y = Random % height;
- // генерируем "цвет" шума - реализация может быть разной
- gray = (BYTE)(Random % 255);
- // расчитываем смещение
- ImageOffset = y * width + x;
- // формируем рабочие данные
- (pImageData+ImageOffset)->Layer.B = (pImageData+ImageOffset)->Layer.B * gray / 255;
- (pImageData+ImageOffset)->Layer.G = (pImageData+ImageOffset)->Layer.G * gray / 255;
- (pImageData+ImageOffset)->Layer.R = (pImageData+ImageOffset)->Layer.R * gray / 255;
- }
- }
- //*************************************************************
- typedef struct _HICOLOR
- {
- union
- {
- // цельный цвет
- DWORD Color;
- // составляющие
- struct
- {
- BYTE B;
- BYTE G;
- BYTE R;
- BYTE Alpha;
- } Layer;
- };
- } HICOLOR, *PHICOLOR, *LPHICOLOR;
- //*************************************************************
- //*
- //* Старт программы
- //*
- //*************************************************************
- int main(int Count, char ** pArguments)
- {
- //****
- HANDLE hFile;
- BITMAPFILEHEADER FileHeader;
- BITMAPINFOHEADER InfoHeader;
- LPBYTE pFileData;
- LPHICOLOR pImageData;
- DWORD Size;
- DWORD LineSize;
- DWORD FileOffset;
- DWORD ImageOffset;
- DWORD x;
- DWORD y;
- // открываем файл
- hFile = CreateFile(*(pArguments+1),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
- // читаем заголовок файла
- ReadFile(hFile,(LPVOID)&FileHeader,sizeof(BITMAPFILEHEADER),&Size,NULL);
- // читаем заголовок изображения
- ReadFile(hFile,(LPVOID)&InfoHeader,sizeof(BITMAPINFOHEADER),&Size,NULL);
- // если это изображение R8G8B8
- if( InfoHeader.biBitCount == 24 )
- {
- // выделяем память под данные файла изображения
- pFileData = (LPBYTE)GlobalAlloc(GPTR,InfoHeader.biSizeImage);
- // читаем данные файла изображения
- SetFilePointer(hFile,FileHeader.bfOffBits,NULL,FILE_BEGIN);
- ReadFile(hFile,(LPVOID)pFileData,InfoHeader.biSizeImage,&Size,NULL);
- // закрываем файл
- CloseHandle(hFile);
- // вычисляем размер линии по горизонтали, так как она должна быть выравнена на DWORD
- // это нужно для дальнейших преобразований
- LineSize = InfoHeader.biSizeImage / InfoHeader.biHeight;
- // выделяем память под рабочие данные изображения
- pImageData = (LPHICOLOR)GlobalAlloc(GPTR,InfoHeader.biWidth*InfoHeader.biHeight*sizeof(HICOLOR));
- // формируем рабочее изображение
- for( y=0; y<InfoHeader.biHeight; y++ )
- {
- for( x=0; x<InfoHeader.biWidth; x++ )
- {
- // расчитываем смещения
- FileOffset = y * LineSize + x * 3;
- ImageOffset = y * InfoHeader.biWidth + x;
- // формируем рабочие данные
- (pImageData+ImageOffset)->Layer.Alpha = 0xFF;
- (pImageData+ImageOffset)->Layer.B = *(pFileData+FileOffset);
- (pImageData+ImageOffset)->Layer.G = *(pFileData+FileOffset+1);
- (pImageData+ImageOffset)->Layer.R = *(pFileData+FileOffset+2);
- }
- }
- // освобождаем ранее выделенную память под данные файла изображения
- GlobalFree(pFileData);
- // Изменяем размер
- Resize(&pImageData,(LPDWORD)&InfoHeader.biWidth,(LPDWORD)&InfoHeader.biHeight,InfoHeader.biWidth/2,InfoHeader.biHeight/2);
- // Обрезаем
- Cut(&pImageData,(LPDWORD)&InfoHeader.biWidth,(LPDWORD)&InfoHeader.biHeight,InfoHeader.biWidth/4,InfoHeader.biHeight/4,InfoHeader.biWidth*3/4,InfoHeader.biHeight*3/4);
- // Добавляем шум
- AppendNoise(pImageData,InfoHeader.biWidth,InfoHeader.biHeight);
- // вычисляем размер линии по горизонтали, так как она должна быть выравнена на DWORD
- // это нужно для дальнейших преобразований
- for( LineSize=InfoHeader.biWidth*3; (LineSize & 0x00000003); LineSize++ );
- // заполняем описание нового изображения
- InfoHeader.biSizeImage = LineSize * InfoHeader.biHeight;
- FileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + InfoHeader.biSizeImage;
- // выделяем память под данные файла изображения
- pFileData = (LPBYTE)GlobalAlloc(GPTR,InfoHeader.biSizeImage);
- // формируем готовое изображение
- for( y=0; y<InfoHeader.biHeight; y++ )
- {
- for( x=0; x<InfoHeader.biWidth; x++ )
- {
- // расчитываем смещения
- FileOffset = y * LineSize + x * 3;
- ImageOffset = y * InfoHeader.biWidth + x;
- // формируем рабочие данные
- *(pFileData+FileOffset) = (pImageData+ImageOffset)->Layer.B;
- *(pFileData+FileOffset+1) = (pImageData+ImageOffset)->Layer.G;
- *(pFileData+FileOffset+2) = (pImageData+ImageOffset)->Layer.R;
- }
- }
- // освобождаем ранее выделенную память под рабочие данные изображения
- GlobalFree(pImageData);
- // создаем файл
- hFile = CreateFile(*(pArguments+2),GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,0,NULL);
- // записываем заголовок файла
- WriteFile(hFile,(LPVOID)&FileHeader,sizeof(BITMAPFILEHEADER),&Size,NULL);
- // записываем заголовок изображения
- WriteFile(hFile,(LPVOID)&InfoHeader,sizeof(BITMAPINFOHEADER),&Size,NULL);
- // записываем само изображение
- WriteFile(hFile,(LPVOID)pFileData,InfoHeader.biSizeImage,&Size,NULL);
- // закрываем файл
- CloseHandle(hFile);
- // освобождаем ранее выделенную память под данные файла изображения
- GlobalFree(pFileData);
- }
- // закрываем файл
- else CloseHandle(hFile);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement