1import java.io._ 2object Bmp24Writer { 3 //将加密的数据写入文件 4 def writeEncryptedBmp(bmpPath: String, keys: Array[Int], 5 shift: Int, times: Int, 6 red: Array[Array[Int]], 7 green: Array[Array[Int]], 8 blue: Array[Array[Int]]) = { 9 val width = red(0).length 10 val fos = new FileOutputStream(bmpPath) 11 val dos = new DataOutputStream(fos) 12 13 writeBmp24(dos, red, green ,blue) 14 15 for(i <- 0 until width) 16 print(s"${keys(i)} ") 17 println 18 println(s"times: $times, shift $shift") 19 20 for(i <- 0 until width) 21 dos write(changeByte(keys(i)), 0, 4) 22 23 dos write(changeByte(times), 0, 4) 24 dos write(changeByte(shift), 0, 4) 25 26 dos.flush 27 dos.close 28 dos.close 29 } 30 //将解密后的数据写入文件 31 def writeNormalBmp(bmpPath: String, 32 red: Array[Array[Int]], 33 green: Array[Array[Int]], 34 blue: Array[Array[Int]]) = { 35 val fos = new FileOutputStream(bmpPath) 36 val dos = new DataOutputStream(fos) 37 38 writeBmp24(dos, red, green ,blue) 39 40 dos.flush 41 dos.close 42 fos.close 43 } 44 //写bmp图片的信息头和文件头还有位图数据 45 def writeBmp24(dos: DataOutputStream, 46 red: Array[Array[Int]], 47 green: Array[Array[Int]], 48 blue: Array[Array[Int]]) = { 49 val width = red(0).length 50 val height = red.length 51 52 //14字节的文件头 53 //代表BM 54 val bfType = 0x424d.toShort 55 // bmp文件的大小(2—5字节) 56 val bfSize = 54 + width * height * 3 57 // 位图文件保留字,必须为0(6-7字节) 58 val bfReserved1 = 0 59 // 位图文件保留字,必须为0(8-9字节) 60 val bfReserved2 = 0 61 // 文件头开始到位图实际数据之间的字节的偏移量(10-13字节) 62 val bfOffBits = 54 63 64 65 dos writeShort bfType 66 dos write(changeByte(bfSize), 0, 4) 67 dos write(changeByte(bfReserved1), 0, 2) 68 dos write(changeByte(bfReserved2), 0, 2) 69 dos write(changeByte(bfOffBits), 0, 4) 70 71 //40字节的信息头 72 // 信息头所需的字节数(14-17字节) 73 val biSize = 40 74 // 位图的宽(18-21字节) 75 val biWidth = width 76 // 位图的高(22-25字节) 77 val biHeight = height 78 // 目标设备的级别,必须是1(26-27字节) 79 val biPlanes = 1 80 // 每个像素所需的位数(28-29字节),必须是1位(双色)、 81 // 4位(16色)、8位(256色)或者24位(真彩色)之一。 82 val biBitcount = 24 83 // 位图压缩类型,必须是0(不压缩)(30-33字节)、 84 //1(BI_RLEB压缩类型)或2(BI_RLE4压缩类型)之一。 85 val biCompression = 0 86 // 实际位图图像的大小,即整个实际绘制的图像大小(34-37字节) 87 val biSizeImage = width * height 88 // 位图水平分辨率,每米像素数(38-41字节)这个数是系统默认值 89 val biXPelsPerMeter = 0 90 // 位图垂直分辨率,每米像素数(42-45字节)这个数是系统默认值 91 val biYPelsPerMeter = 0 92 // 位图实际使用的颜色表中的颜色数(46-49字节), 93 // 如果为0的话,说明全部使用了 94 val biClrUsed = 0 95 // 位图显示过程中重要的颜色数(50-53字节), 96 // 如果为0的话,说明全部重要 97 val biClrImportant = 0 98 99 // 因为是大端存储,那么也就是说同样会大端输出。 100 // 所以首先调用方法将int数据转变为多个byte数据, 101 // 并且按小端存储的顺序. 102 dos write(changeByte(biSize), 0, 4) 103 dos write(changeByte(biWidth), 0, 4) 104 dos write(changeByte(biHeight), 0, 4) 105 dos write(changeByte(biPlanes), 0, 2) 106 dos write(changeByte(biBitcount), 0, 2) 107 dos write(changeByte(biCompression), 0, 4) 108 dos write(changeByte(biSizeImage), 0, 4) 109 dos write(changeByte(biXPelsPerMeter), 0, 4) 110 dos write(changeByte(biYPelsPerMeter), 0, 4) 111 dos write(changeByte(biClrUsed), 0, 4) 112 dos write(changeByte(biClrImportant), 0, 4) 113 114 // 因为是24位图,所以没有颜色表 115 // 通过遍历输入位图数据 116 // 这里遍历的时候注意,在计算机内存中位图数据 117 // 是从左到右,从下到上来保存的, 118 // 也就是说实际图像的第一行的点在内存是最后一行 119 for(i <- height - 1 to 0 by -1){ 120 for(j <- 0 to width - 1){ 121 dos write(changeByte(blue(i)(j)), 0, 1) 122 dos write(changeByte(green(i)(j)), 0, 1) 123 dos write(changeByte(red(i)(j)), 0, 1) 124 } 125 } 126 127 } 128 129 // 将一个int数据转为按小端顺序排列的字节数组 130 def changeByte(data: Int): Array[Byte] = 131 Array( 132 ((data << 24) >> 24).toByte, 133 ((data << 16) >> 24).toByte, 134 ((data << 8) >> 24).toByte, 135 (data >> 24).toByte 136 ) 137 138 // 将四个字节解析成int数据 139 def ChangeInt(array2: Array[Byte], start: Int) = { 140 val i = 141 ((array2(start) & 0xff) << 24) | ((array2(start - 1) & 0xff) << 16) 142 val j = 143 ((array2(start - 2) & 0xff) << 8) | (array2(start - 3) & 0xff) 144 i | j 145 } 146 147 // 读取rgb数据 148 def getInf(bis: BufferedInputStream, height: Int, width: Int) = { 149 150 val red = Array.ofDim[Int](height, width) 151 val green = Array.ofDim[Int](height, width) 152 val blue = Array.ofDim[Int](height, width) 153 154 // 计算系统在每行的填充的字节数 155 val m = width * 3 % 4 156 var skip_width = 0 157 if(m != 0) 158 skip_width = 4 - m 159 160 for (i <- height - 1 to 0 by -1) { 161 for (j <- 0 to width - 1) { 162 blue(i)(j) = bis.read 163 green(i)(j) = bis.read 164 red(i)(j) = bis.read 165 if (j == 0) { 166 bis skip(skip_width) 167 } 168 } 169 } 170 (red, green, blue) 171 } 172 173}
Bmp24Writer代码
Stella981
2021-10-11
1024 0 0
点赞
收藏
评论区
加载中...