图片bmp格式转换为jpg格式
一下代码经过个人测试,可用
注意:将jpg格式的图片重命名为bmp格式,在该代码中是不能转换的,会报空值异常!而且IE10是显示不了这样的图片的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | import java.awt.Image; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.awt.image.MemoryImageSource; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class BmpReader { /** * 图片格式转换 BMP -> JPG * @param file * @param dstFile */ public static void bmpTojpg(String file, String dstFile) { try { FileInputStream in = new FileInputStream(file); Image TheImage = read(in); int wideth = TheImage.getWidth( null ); int height = TheImage.getHeight( null ); BufferedImage tag = new BufferedImage(wideth, height,BufferedImage.TYPE_INT_RGB); tag.getGraphics().drawImage(TheImage, 0 , 0 , wideth, height, null ); FileOutputStream out = new FileOutputStream(dstFile); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(tag); out.close(); } catch (Exception e) { System.out.println(e); } } public static int constructInt( byte [] in, int offset) { int ret = (( int ) in[offset + 3 ] & 0xff ); ret = (ret << 8 ) | (( int ) in[offset + 2 ] & 0xff ); ret = (ret << 8 ) | (( int ) in[offset + 1 ] & 0xff ); ret = (ret << 8 ) | (( int ) in[offset + 0 ] & 0xff ); return (ret); } public static int constructInt3( byte [] in, int offset) { int ret = 0xff ; ret = (ret << 8 ) | (( int ) in[offset + 2 ] & 0xff ); ret = (ret << 8 ) | (( int ) in[offset + 1 ] & 0xff ); ret = (ret << 8 ) | (( int ) in[offset + 0 ] & 0xff ); return (ret); } public static long constructLong( byte [] in, int offset) { long ret = (( long ) in[offset + 7 ] & 0xff ); ret |= (ret << 8 ) | (( long ) in[offset + 6 ] & 0xff ); ret |= (ret << 8 ) | (( long ) in[offset + 5 ] & 0xff ); ret |= (ret << 8 ) | (( long ) in[offset + 4 ] & 0xff ); ret |= (ret << 8 ) | (( long ) in[offset + 3 ] & 0xff ); ret |= (ret << 8 ) | (( long ) in[offset + 2 ] & 0xff ); ret |= (ret << 8 ) | (( long ) in[offset + 1 ] & 0xff ); ret |= (ret << 8 ) | (( long ) in[offset + 0 ] & 0xff ); return (ret); } public static double constructDouble( byte [] in, int offset) { long ret = constructLong(in, offset); return (Double.longBitsToDouble(ret)); } public static short constructShort( byte [] in, int offset) { short ret = ( short ) (( short ) in[offset + 1 ] & 0xff ); ret = ( short ) ((ret << 8 ) | ( short ) (( short ) in[offset + 0 ] & 0xff )); return (ret); } static class BitmapHeader { public int iSize, ibiSize, iWidth, iHeight, iPlanes, iBitcount, iCompression, iSizeimage, iXpm, iYpm, iClrused, iClrimp; // 读取bmp文件头信息 public void read(FileInputStream fs) throws IOException { final int bflen = 14 ; byte bf[] = new byte [bflen]; fs.read(bf, 0 , bflen); final int bilen = 40 ; byte bi[] = new byte [bilen]; fs.read(bi, 0 , bilen); iSize = constructInt(bf, 2 ); ibiSize = constructInt(bi, 2 ); iWidth = constructInt(bi, 4 ); iHeight = constructInt(bi, 8 ); iPlanes = constructShort(bi, 12 ); iBitcount = constructShort(bi, 14 ); iCompression = constructInt(bi, 16 ); iSizeimage = constructInt(bi, 20 ); iXpm = constructInt(bi, 24 ); iYpm = constructInt(bi, 28 ); iClrused = constructInt(bi, 32 ); iClrimp = constructInt(bi, 36 ); } } public static Image read(FileInputStream fs) { try { BitmapHeader bh = new BitmapHeader(); bh.read(fs); if (bh.iBitcount == 24 ) { return (readImage24(fs, bh)); } if (bh.iBitcount == 32 ) { return (readImage32(fs, bh)); } fs.close(); } catch (IOException e) { System.out.println(e); } return ( null ); } // 24位 protected static Image readImage24(FileInputStream fs, BitmapHeader bh) throws IOException { Image image; if (bh.iSizeimage == 0 ) { bh.iSizeimage = ((((bh.iWidth * bh.iBitcount) + 31 ) & ~ 31 ) >> 3 ); bh.iSizeimage *= bh.iHeight; } int npad = (bh.iSizeimage / bh.iHeight) - bh.iWidth * 3 ; int ndata[] = new int [bh.iHeight * bh.iWidth]; byte brgb[] = new byte [(bh.iWidth + npad) * 3 * bh.iHeight]; fs.read(brgb, 0 , (bh.iWidth + npad) * 3 * bh.iHeight); int nindex = 0 ; for ( int j = 0 ; j < bh.iHeight; j++) { for ( int i = 0 ; i < bh.iWidth; i++) { ndata[bh.iWidth * (bh.iHeight - j - 1 ) + i] = constructInt3( brgb, nindex); nindex += 3 ; } nindex += npad; } image = Toolkit.getDefaultToolkit().createImage( new MemoryImageSource(bh.iWidth, bh.iHeight, ndata, 0 , bh.iWidth)); fs.close(); return (image); } // 32位 protected static Image readImage32(FileInputStream fs, BitmapHeader bh) throws IOException { Image image; int ndata[] = new int [bh.iHeight * bh.iWidth]; byte brgb[] = new byte [bh.iWidth * 4 * bh.iHeight]; fs.read(brgb, 0 , bh.iWidth * 4 * bh.iHeight); int nindex = 0 ; for ( int j = 0 ; j < bh.iHeight; j++) { for ( int i = 0 ; i < bh.iWidth; i++) { ndata[bh.iWidth * (bh.iHeight - j - 1 ) + i] = constructInt3( brgb, nindex); nindex += 4 ; } } image = Toolkit.getDefaultToolkit().createImage( new MemoryImageSource(bh.iWidth, bh.iHeight, ndata, 0 , bh.iWidth)); fs.close(); return (image); } public static void main(String[] args) { String srcfile = "D:\\33.bmp" ; String dstFile = "D:\\33.jpg" ; bmpTojpg(srcfile, dstFile); } } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 开发的设计和重构,为开发效率服务
· 从零开始开发一个 MCP Server!
· Ai满嘴顺口溜,想考研?浪费我几个小时
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密