一,实现效果:图片剪切, 图片拼接
-------切割后----->
切割后的小图片
拼图的效果与此类似.
二,实现思想
利用上一篇所展示的libpng读写图片的函数,读出图片的数据域,然后对数据域进行"剪切"或者拼接获得新图片的数据域,最后通过libpng的库函数写入图片即可.
三,剪切图片的核心代码(代码内含注释)
思路:读出一张大图片的数据域buff, 按照数据与图片中像素对应的原则, 依次获取切割后每个小图片的数据域png_buff(像素矩阵)
难点:由于代码中图片数据域的表示方法为一维数组,导致获取指定行和列的某个像素时需要对一维数组做处理当做二维的来使用
代码:
1 void PngOper::run() 2 { 3 cout << "你好" << endl; 4 char * filePath = "C:\\Users\\Administrator\\Desktop\\切图 - 副本\\map_1001.png"; 5 int width = 0; 6 int height = 0; 7 8 readPngInfo(filePath, &width, &height); 9 cout << "读取信息:" << width << "*" << height << endl; 10 11 12 //小块儿图片的宽,高 13 int cfg_width = 192; 14 int cfg_height = 180; 15 16 //计算分割的小图片的行,列数目 17 int gW = width / cfg_width; 18 int exceedWidth = width % cfg_width; 19 int gH = height / cfg_height; 20 int exceedHeight = height % cfg_height; 21 22 int h = exceedHeight > 0 ? (gH + 1) : gH; 23 int w = exceedWidth > 0 ? (gW + 1) : gW; 24 25 //读取大图片数据域 26 RGBA_data *buff = (RGBA_data *)malloc(width*height*sizeof(RGBA_data)); 27 load_png_image(filePath, &width, &height, buff); 28 29 //分配小块儿地图的数据域 30 RGBA_data *png_buff = (RGBA_data *)malloc(cfg_width * cfg_height * sizeof(RGBA_data)); 31 for (int i = 0; i < h; i++) 32 { 33 for (int j = 0; j < w; j++) 34 { 35 //1.获取png_buff数据域 36 buffCopy(buff, width, height, png_buff, cfg_width, cfg_height, j*cfg_width, i*cfg_height); 37 //2.写图片 38 int idx = i*w + j + 1; 39 string fileName = "C:\\Users\\Administrator\\Desktop\\切图 - 副本\\" + to_string(idx) + ".png"; 40 write_RGBA_Image(fileName.c_str(), cfg_width, cfg_height, "test", png_buff); 41 } 42 } 43 44 if (buff != nullptr) 45 { 46 free(buff); 47 buff = nullptr; 48 } 49 if (png_buff != nullptr) 50 { 51 free(png_buff); 52 png_buff = nullptr; 53 } 54 }
四,注意
png图片的color_type有多种,包括熟知的RGB类型与RGBA类型,通过读取图片信息可以获取该内容.
进行图片读写时要兼顾多种类型的color_type
时间: 2024-10-07 06:29:03