原图:调用dot和convolution后的图像:位图图像前54byte为文件头,其后为像素信息,定义xyz函数访问(x,y)处的第z个颜色分量byte_t Image::xyz(int64_t x, int64_t y, int64_t z) { x lader(x, (int64_t)0, (int64_t)this-bih.width - 1); y lader(y, (int64_t)0, (int64_t)this-bih.height - 1); return this-bitmap[y * this-row_size x * 3 z]; }Image.h头文件包含图像文件读取和修改#pragma once #include iostream #include fstream #include utility #include cmath typedef unsigned char byte_t; typedef unsigned short word_t; const double pi acos(-1); template typename T struct Point { T x; T y; Point(T _x, T _y) : x{ _x }, y{ _y } {} PointT operator (PointT p) { this-x p.x; this-y p.y; return *this; } PointT operator - (PointT p) { this-x - p.x; this-y - p.y; return *this; } PointT operator * (PointT p) { this-x * p.x; this-y * p.y; return *this; } PointT operator / (PointT p) { this-x / p.x; this-y / p.y; return *this; } PointT operator (PointT p) { return PointT(this-x p.x, this-y p.y); } PointT operator - (PointT p) { return PointT(this-x - p.x, this-y - p.y); } PointT operator * (PointT p) { return PointT(this-x * p.x, this-y * p.y); } PointT operator / (PointT p) { return PointT(this-x / p.x, this-y / p.y); } PointT operator (T t) { return PointT(this-x t, this-y t); } PointT operator - (T t) { return PointT(this-x - t, this-y - t); } PointT operator * (T t) { return PointT(this-x * t, this-y * t); } PointT operator / (T t) { return PointT(this-x / t, this-y / t); } }; double fract(double _X) { return _X - floor(_X); } int64_t floor_int(double _X) { return (int64_t)floor(_X); } int64_t ceil_int(double _X) { return (int64_t)ceil(_X); } void pause(const char* text press any key to continue...\n) { std::cout text; int ch getchar(); } template typename T T lader(T t, T l, T r) { return t l ? l : (t r ? r : t); } double color_lader(double t) { return lader(t, 0.0, 255.0); } byte_t discretization(byte_t val, int num) { return byte_t(byte_t(val / 256.0 * num) * (255 / num)); } byte_t line(byte_t val, double k, double b) { return byte_t((val / 255.0 * k b) * 255.0); } byte_t sin_2(byte_t val) { double t sin(val / 512.0 * pi); t t * t * 255.0; return byte_t(t); } byte_t sin_n(byte_t val, double num) { double t sin(val / 512.0 * pi); t pow(t, (double)num) * 255.0; return byte_t(t); } Pointdouble rotate(Pointdouble p, double theta) { double r sqrt(p.x * p.x p.y * p.y); return Pointdouble(cos(r * theta) * p.x - sin(r * theta) * p.y, sin(r * theta) * p.x cos(r * theta) * p.y); } Pointdouble quadrilateral(Pointdouble p, Pointdouble p0, Pointdouble p1, Pointdouble p2, Pointdouble p3) { p (p 1.0) * 0.5; return p0 * p.x * p.y p1 * (1.0 - p.x) * p.y p2 * (1.0 - p.x) * (1.0 - p.y) p3 * p.x * (1.0 - p.y); } #pragma once #include base.h #pragma pack(push, 1) // BMP文件头结构体 struct BitmapFileHeader { uint16_t type; //BMP文件的类型必须是 BM 才表示是BMP文件 uint32_t size; //文件大小包括像素数据和所有头部信息 uint16_t reserved1; //保留字必须设置为0 uint16_t reserved2; //保留字必须设置为0 uint32_t offbits; //从文件开始到像素数据开始的字节偏移量 }; // BMP信息头结构体 struct BitmapInfoHeader { uint32_t size; //本结构体的大小 int32_t width; //图像的宽度像素 int32_t height; //图像的高度像素 uint16_t planes; //颜色平面数必须设置为1 uint16_t bitcount; //每个像素的位数1, 4, 8, 16, 24, 32 uint32_t compression; //使用的压缩类型 uint32_t sizeimage; //图像的大小字节 int32_t xpels_per_meter; //水平分辨率像素/米 int32_t ypels_per_meter; //垂直分辨率像素/米 uint32_t color_used; //在位图中使用的颜色索引数 uint32_t color_important; //对图像显示有重要影响的颜色索引数 }; #pragma pack(pop) struct Image { byte_t* bitmap nullptr; uint32_t row_size{}; BitmapFileHeader bfh{}; BitmapInfoHeader bih{}; Image() default; ~Image() default; errno_t open(const char* file); errno_t restore(const char* file); void free(); void header(Image img); Image operator (Image img); Image operator (Image img) noexcept; byte_t xyz(int64_t x, int64_t y, int64_t z); }; errno_t Image::open(const char* file) { puts(file); std::ifstream in(file, std::ios::binary); if (in.fail()) return -1; in.read((char*)(this-bfh), sizeof(BitmapFileHeader)); in.read((char*)(this-bih), sizeof(BitmapInfoHeader)); in.seekg(this-bfh.offbits, std::ios::beg); this-bitmap new byte_t[this-bih.sizeimage]; this-row_size ((this-bih.width * 3 3) / 4) * 4; in.read((char*)(bitmap), bih.sizeimage); in.close(); std::cout Width: this-bih.width std::endl; std::cout Heigth: this-bih.height std::endl; return 0; } errno_t Image::restore(const char* file) { std::ofstream out(file, std::ios::binary); if (out.fail()) return -1; out.write((char*)(this-bfh), sizeof(BitmapFileHeader)); out.write((char*)(this-bih), sizeof(BitmapInfoHeader)); out.write((char*)(bitmap), bih.sizeimage); out.close(); std::cout OK! std::endl; return 0; } void Image::free() { delete[] this-bitmap; this-bitmap nullptr; this-row_size 0; this-bfh BitmapFileHeader(); this-bih BitmapInfoHeader(); } void Image::header(Image img) { delete[] this-bitmap; this-bitmap new byte_t[img.bih.sizeimage]; this-row_size img.row_size; this-bfh img.bfh; this-bih img.bih; } Image Image::operator (Image img) { delete[] this-bitmap; this-bitmap new byte_t[img.bih.sizeimage]; std::copy_n(img.bitmap, img.bih.sizeimage, this-bitmap); this-row_size img.row_size; this-bfh img.bfh; this-bih img.bih; return img; } Image Image::operator (Image img) noexcept { delete[] this-bitmap; this-bitmap img.bitmap; this-row_size img.row_size; this-bfh img.bfh; this-bih img.bih; return *this; } byte_t Image::xyz(int64_t x, int64_t y, int64_t z) { x lader(x, (int64_t)0, (int64_t)this-bih.width - 1); y lader(y, (int64_t)0, (int64_t)this-bih.height - 1); return this-bitmap[y * this-row_size x * 3 z]; } void each(Image src, byte_t(*func)(byte_t)) { Image dst; dst.header(src); for (size_t i 0; i src.bih.sizeimage; i) dst.bitmap[i] func(src.bitmap[i]); src std::move(dst); } template typename ...T void each(Image src, byte_t(*func)(byte_t, T...), T... arg) { Image dst; dst.header(src); for (size_t i 0; i src.bih.sizeimage; i) dst.bitmap[i] func(src.bitmap[i], arg...); src std::move(dst); } void dot(Image src, double vec3[3]) { Image dst; dst.header(src); for (size_t x 0; x src.bih.width; x) for (size_t y 0; y src.bih.height; y) { double t vec3[0] * src.xyz(x, y, 0) vec3[1] * src.xyz(x, y, 1) vec3[2] * src.xyz(x, y, 2); dst.xyz(x, y, 0) byte_t(t 0.5); dst.xyz(x, y, 1) byte_t(t 0.5); dst.xyz(x, y, 2) byte_t(t 0.5); } src std::move(dst); } void dot(Image src, double vec3[3], double(*func)(double)) { Image dst; dst.header(src); for (size_t x 0; x src.bih.width; x) for (size_t y 0; y src.bih.height; y) { double t vec3[0] * src.xyz(x, y, 0) vec3[1] * src.xyz(x, y, 1) vec3[2] * src.xyz(x, y, 2); t func(t); dst.xyz(x, y, 0) byte_t(t 0.5); dst.xyz(x, y, 1) byte_t(t 0.5); dst.xyz(x, y, 2) byte_t(t 0.5); } src std::move(dst); } void convolution(Image src, double mat3[3][3]) { Image dst; dst.header(src); for (int64_t x 0; x (int64_t)src.bih.width; x) for (int64_t y 0; y (int64_t)src.bih.height; y) for (int64_t z 0; z 3; z) { double t 0.0; for (int64_t dx -1; dx 1; dx) for (int64_t dy -1; dy 1; dy) t mat3[dx 1][dy 1] * src.xyz(x dx, y dy, z); dst.xyz(x, y, z) byte_t(t 0.5); } src std::move(dst); } void convolution(Image src, double mat3[3][3], double(*func)(double)) { Image dst; dst.header(src); for (int64_t x 0; x (int64_t)src.bih.width; x) for (int64_t y 0; y (int64_t)src.bih.height; y) for (int64_t z 0; z 3; z) { double t 0.0; for (int64_t dx -1; dx 1; dx) for (int64_t dy -1; dy 1; dy) t mat3[dx 1][dy 1] * src.xyz(x dx, y dy, z); t func(t); dst.xyz(x, y, z) byte_t(t 0.5); } src std::move(dst); } void sampler(Image src, Pointdouble(*func)(Pointdouble)) { Image dst; dst.header(src); for (int64_t x 0; x src.bih.width; x) for (int64_t y 0; y src.bih.height; y) { Pointdouble p func(Pointdouble((double)x / src.bih.width * 2.0 - 1.0, (double)y / src.bih.height * 2.0 - 1.0)); p (p 1.0) * 0.5 * Pointdouble((double)src.bih.width, (double)src.bih.height); int64_t xi floor_int(p.x); int64_t yi floor_int(p.y); double xf fract(p.x); double yf fract(p.y); for (int64_t z 0; z 3; z) { double t src.xyz(xi, yi, z) * (1.0 - xf) * (1.0 - yf) src.xyz(xi 1, yi, z) * xf * (1.0 - yf) src.xyz(xi, yi 1, z) * (1.0 - xf) * yf src.xyz(xi 1, yi 1, z) * xf * yf; dst.xyz(x, y, z) byte_t(t 0.5); } } src std::move(dst); } template typename ...T void sampler(Image src, Pointdouble(*func)(Pointdouble, T...), T...arg) { Image dst; dst.header(src); for (int64_t x 0; x src.bih.width; x) for (int64_t y 0; y src.bih.height; y) { Pointdouble p func(Pointdouble((double)x / src.bih.width * 2.0 - 1.0, (double)y / src.bih.height * 2.0 - 1.0), arg...); p (p 1.0) * 0.5 * Pointdouble((double)src.bih.width, (double)src.bih.height); int64_t xi floor_int(p.x); int64_t yi floor_int(p.y); double xf fract(p.x); double yf fract(p.y); for (int64_t z 0; z 3; z) { double t src.xyz(xi, yi, z) * (1.0 - xf) * (1.0 - yf) src.xyz(xi 1, yi, z) * xf * (1.0 - yf) src.xyz(xi, yi 1, z) * (1.0 - xf) * yf src.xyz(xi 1, yi 1, z) * xf * yf; dst.xyz(x, y, z) byte_t(t 0.5); } } src std::move(dst); }
阅读完成 · 觉得有帮助?