图片转码 webp 转 png、jpg

本文介绍了如何使用Java工具处理安卓上传的图片,使其能在iOS设备上正常显示。通过修改图片头部信息,解决了不同平台图片格式不兼容的问题,重点在于ImageUtils工具类的实现和文件头识别技巧。

最近项目遇到一个问题,安卓上传的图片,IOS看不了,IOS呢 又不愿意更新图片展示框架,所以,只有安卓这边做处理啦。开始直接修改图片后缀,但是发现并不能解决问题,后面通过解析图片的头部文件,修改头部文件类型,就可以了。

下面是工具类:

package com.xxxx.review.activity.issue;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.ArrayMap;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * 2022-02-16
 * 文件转换为 JPG
 */
public class ImageUtils {

    private static final String TAG = "PicUtils";
    private static final String PNG = "png";
    private static final String JPG = "jpg";
    private static final String JPEG = "jpeg";
    private static final String BMP = "bmp";
    // private static final String[] imgSuffixes = {PNG, JPG, JPEG, BMP};
    private static final List<String> fileSuffixes = Arrays.asList(PNG, JPG, JPEG, BMP);
    // 缓存文件头信息-文件头信息
    private static final ArrayMap<String, String> mFileTypes = new ArrayMap<String, String>();

    static {
        // images
        mFileTypes.put("FFD8FFE0", JPG);
        mFileTypes.put("89504E47", PNG);
        mFileTypes.put("424D5A52", BMP);
    }

    public static void ImageToJPGList(List<String> dirs) {
        for (int i = 0; i < dirs.size(); i++) {
            ImgToJPG(new File(dirs.get(i)));
        }
    }

    /**
     * 指定文件夹中的图片文件转成JPG格式
     *
     * @param dir 图片的所在文件夹路径
     */
    public static void ImgToJPG(File dir) {
        String filePath = "";
        //先通过后缀名,过滤非图片
        String fileType = dir.getName().substring(dir.getName().lastIndexOf('.') + 1);
        if (fileSuffixes.contains(fileType.toLowerCase())) {
            filePath = dir.getPath();
            String imgType = mFileTypes.get(getFileHeader(filePath)); //获取真正的文件头
            convertToJpg(filePath, filePath.substring(0, filePath.lastIndexOf('.') + 1) + JPG);
            /*if (!TextUtils.isEmpty(imgType) && !imgType.equals(JPG)) {
                convertToJpg(filePath, filePath.substring(0, filePath.lastIndexOf('.') + 1) + JPG);
            }*/
        }
    }

    /**
     * 转换成JPG格式图片 并将原照片删除
     *
     * @param pngFilePath png或者bmp照片
     * @param jpgFilePath jpg照片
     */
    private static void convertToJpg(String pngFilePath, String jpgFilePath) {
        Bitmap bitmap = BitmapFactory.decodeFile(pngFilePath);
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(jpgFilePath));
            if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos)) {
                bos.flush();
            }
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            bitmap.recycle();
            bitmap = null;
        }
        //删除非JPG照片
        if (!pngFilePath.equals(jpgFilePath)) {
            File oldImg = new File(pngFilePath);
            oldImg.delete();
        }
    }


    /**
     * 根据文件路径获取文件头信息
     *
     * @param filePath 文件路径
     * @return 文件头信息
     */
    private static String getFileHeader(String filePath) {
        FileInputStream is = null;
        String value = null;
        try {
            is = new FileInputStream(filePath);
            byte[] b = new byte[4];
            is.read(b, 0, b.length);
            value = bytesToHexString(b);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return value;
    }

    /**
     * 将要读取文件头信息的文件的byte数组转换成string类型表示
     *
     * @param src 要读取文件头信息的文件的byte数组
     * @return 文件头信息
     */
    private static String bytesToHexString(byte[] src) {
        StringBuilder builder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return "";
        }
        for (int i = 0; i < src.length; i++) {
            // 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式,并转换为大写
            String hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();
            if (hv.length() < 2) {
                builder.append(0);
            }
            builder.append(hv);
        }
        return builder.toString();
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值