Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma pack(1)
- #include <bits/stdc++.h>
- using namespace std;
- struct Pixel {
- unsigned char R;
- unsigned char G;
- unsigned char B;
- Pixel(unsigned char r = 0, unsigned char g = 0, unsigned char b = 0) {
- R = r;
- G = g;
- B = b;
- }
- };
- class Bitmap {
- public:
- unsigned char* info_header;
- unsigned char* file_header;
- unsigned char* pixel_array;
- Bitmap() {
- info_header = file_header = pixel_array = nullptr;
- }
- ~Bitmap() {
- if(info_header) free(info_header);
- if(file_header) free(file_header);
- if(pixel_array) free(pixel_array);
- }
- void load(const char* filename) {
- FILE* f = fopen(filename, "rb");
- file_header = (unsigned char*) malloc(14 * sizeof(unsigned char));
- fread(file_header, sizeof(unsigned char), 14 * sizeof(unsigned char), f);
- info_header = (unsigned char*) malloc(info_headersize() * sizeof(unsigned char));
- fread(info_header, sizeof(unsigned char), info_headersize() * sizeof(unsigned char), f);
- pixel_array = (unsigned char*) malloc(pixel_arraysize() * sizeof(unsigned char));
- fread(pixel_array, sizeof(unsigned char), pixel_arraysize() * sizeof(unsigned char), f);
- fclose(f);
- }
- void load(Bitmap &origin) {
- file_header = (unsigned char*) malloc(14 * sizeof(unsigned char));
- memcpy(file_header, origin.file_header, 14 * sizeof(unsigned char));
- info_header = (unsigned char*) malloc(origin.info_headersize() * sizeof(unsigned char));
- memcpy(info_header, origin.info_header, origin.info_headersize() * sizeof(unsigned char));
- pixel_array = (unsigned char*) malloc(origin.pixel_arraysize() * sizeof(unsigned char));
- memcpy(pixel_array, origin.pixel_array, origin.pixel_arraysize() * sizeof(unsigned char));
- }
- int info_headersize() {
- if(file_header) {
- return (*(int*)&file_header[10] - 14);
- }
- return 0;
- }
- int pixel_arraysize() {
- if(file_header) {
- return (*(int*)&file_header[2] - *(int*)&file_header[10]);
- }
- return 0;
- }
- int getWidth() {
- if(info_header) {
- return (*(int*)&info_header[4]);
- }
- return 0;
- }
- int getHeight() {
- if(info_header) {
- return (*(int*)&info_header[8]);
- }
- return 0;
- }
- void output(const char* filename) {
- FILE* w = fopen(filename, "wb");
- fwrite(file_header, sizeof(unsigned char), 14 * sizeof(unsigned char), w);
- fwrite(info_header, sizeof(unsigned char), info_headersize() * sizeof(unsigned char), w);
- fwrite(pixel_array, sizeof(unsigned char), pixel_arraysize() * sizeof(unsigned char), w);
- fclose(w);
- return;
- }
- };
- bool compare(Pixel &a, Pixel &b) {
- return ((a.B << 16) + (a.G << 8) + a.R) < ((b.B << 16) + (b.G << 8) + b.R);
- }
- Bitmap transformMedia(Bitmap &origin, int w, int h) {
- Bitmap transformed;
- transformed.load(origin);
- int height = origin.getHeight();
- int width = origin.getWidth();
- int row_padded = (width*3 + 3) & (~3);
- int sumr, sumg, sumb, n;
- for(int i = 0; i < height; i++) {
- for(int j = 0; j < width; j++) {
- sumr = 0; sumg = 0; sumb = 0; n = 0;
- for(int x = -w/2; x <= w/2; x++) {
- for(int y = -h/2; y <= h/2; y++) {
- if (i + y >= 0 && j + x >= 0 && j + x < width && i + y < height) {
- n++;
- sumr += origin.pixel_array[(i + y)*row_padded + (j + x)*3 + 2];
- sumg += origin.pixel_array[(i + y)*row_padded + (j + x)*3 + 1];
- sumb += origin.pixel_array[(i + y)*row_padded + (j + x)*3];
- }
- }
- }
- if(n > 0) {
- transformed.pixel_array[i*row_padded + j*3 + 2] = sumr/n;
- transformed.pixel_array[i*row_padded + j*3 + 1] = sumg/n;
- transformed.pixel_array[i*row_padded + j*3] = sumb/n;
- }
- }
- }
- return transformed;
- }
- Bitmap transformMediana(Bitmap &origin, int w, int h) {
- Bitmap transformed;
- transformed.load(origin);
- int height = origin.getHeight();
- int width = origin.getWidth();
- int row_padded = (width*3 + 3) & (~3);
- int n;
- vector<Pixel> tmpvec;
- for(int i = 0; i < height; i++) {
- for(int j = 0; j < width; j++) {
- n = 0;
- for(int x = -w/2; x <= w/2; x++) {
- for(int y = -h/2; y <= h/2; y++) {
- if (i + y >= 0 && j + x >= 0 && j + x < width && i + y < height) {
- n++;
- Pixel tmp(origin.pixel_array[(i + y)*row_padded + (j + x)*3 + 2], origin.pixel_array[(i + y)*row_padded + (j + x)*3 + 1], origin.pixel_array[(i + y)*row_padded + (j + x)*3]);
- tmpvec.push_back(tmp);
- }
- }
- }
- sort(tmpvec.begin(), tmpvec.end(), compare);
- if(n > 0) {
- transformed.pixel_array[i*row_padded + j*3 + 2] = tmpvec[n / 2].R;
- transformed.pixel_array[i*row_padded + j*3 + 1] = tmpvec[n / 2].G;
- transformed.pixel_array[i*row_padded + j*3] = tmpvec[n / 2].B;
- }
- tmpvec.clear();
- }
- }
- return transformed;
- }
- Bitmap transformGrayscale(Bitmap &origin, double r = 0.2126, double g = 0.7152, double b = 0.0722, double divisor = 1) {
- Bitmap transformed;
- transformed.load(origin);
- int height = origin.getHeight();
- int width = origin.getWidth();
- int row_padded = (width*3 + 3) & (~3);
- unsigned char Y;
- for(int i = 0; i < height; i++) {
- for(int j = 0; j < width; j++) {
- Y = (origin.pixel_array[i*row_padded + j*3 + 2] * r + origin.pixel_array[i*row_padded + j*3 + 1] * g + origin.pixel_array[i*row_padded + j*3] * b) / divisor;
- transformed.pixel_array[i*row_padded + j*3 + 2] = Y;
- transformed.pixel_array[i*row_padded + j*3 + 1] = Y;
- transformed.pixel_array[i*row_padded + j*3] = Y;
- }
- }
- return transformed;
- }
- int main() {
- Bitmap data;
- data.load("data.bmp");
- Bitmap media3x3 = transformMedia(data, 3, 3);
- Bitmap media9x9 = transformMedia(data, 9, 9);
- Bitmap mediana3x3 = transformMediana(data, 3, 3);
- Bitmap mediana9x9 = transformMediana(data, 9, 9);
- Bitmap grayscale = transformGrayscale(data);
- Bitmap grayscalem = transformGrayscale(data, 1, 1, 1, 3);
- media3x3.output("media3x3.bmp");
- media9x9.output("media9x9.bmp");
- mediana3x3.output("mediana3x3.bmp");
- mediana9x9.output("mediana9x9.bmp");
- grayscale.output("grayscale.bmp"); // Luminance-preserving.
- grayscalem.output("grayscalem.bmp"); // Avg of r, g and b.
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement