.pgr照片文件解析,C++与Java存储数据差别大小端模式

2023-11-09

1. .pgr是什么?

.pgr文件是二进制的图像文件,可以用普通的文本文件打开,或者查看十六进制的文本信息;

读取需要了解~~~非常重要 !!!

  • 基本数据类型的大小端存储模式
  • 表头Header

详细信息可参考:http://www.powergrep.com/manual/PowerGREP.pdf

在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述

2. C++与Java存储数据差别——大小端模式

Java是大端模式,C是小端模式;

以int为类,大端模式:高位存高位,低位存地位;
小端模式:高位存地位,地位存高位

  • 如 大端:ABCD 小端:DCBA

float,double存储为 符号位,指数位,小数位,更复杂一些;

3. Java读取小端模式数据示例代码

  • 可以用BufferTest
  • 利用移位方法
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/*************************************
 * Class Name: doubleConvert
 * Description:〈大小端转换〉
 * @create 2020/8/19
 * @since 1.0.0
 ************************************/
public class doubleConvert {

    /**
     * 向将bytes添加到另一个bytes结尾,并返回位置
     *
     * @param buff 目标数组
     * @param pos  目标数组放置的起始位置
     * @param lens 添加的长度
     * @param dx   要添加的数组
     * @return lens添加的长度
     */
    public static int addToBuff(byte[] buff, int pos, int lens, byte[] dx) {
        System.arraycopy(dx, 0, buff, pos, lens);
        return lens;
    }

    /**
     * 获得bytes的一段数据
     *
     * @param buff     原byte数组
     * @param startPos 起始位置
     * @param lenth    获取的长度
     * @return 返回获得的byte数组
     */
    public static byte[] getFromBuff(byte[] buff, int startPos, int lenth) {
        byte[] bytes = new byte[lenth];
        System.arraycopy(buff, startPos, bytes, 0, lenth);
        return bytes;
    }

    /**
     * double转byte数组,小端模式
     *
     * @param d
     * @return
     */
    public static byte[] doubleToBytes_Little(double d) {
        long l = Double.doubleToLongBits(d);
        byte b[] = new byte[8];
        b[7] = (byte) (0xff & (l >> 56));
        b[6] = (byte) (0xff & (l >> 48));
        b[5] = (byte) (0xff & (l >> 40));
        b[4] = (byte) (0xff & (l >> 32));
        b[3] = (byte) (0xff & (l >> 24));
        b[2] = (byte) (0xff & (l >> 16));
        b[1] = (byte) (0xff & (l >> 8));
        b[0] = (byte) (0xff & l);
        return b;
    }

    /**
     * double转byte数组,大端模式
     *
     * @param d
     * @return
     */
    public static byte[] doubleToBytes_Big(double d) {
        long l = Double.doubleToLongBits(d);
        byte b[] = new byte[8];
        b[0] = (byte) (0xff & (l >> 56));
        b[1] = (byte) (0xff & (l >> 48));
        b[2] = (byte) (0xff & (l >> 40));
        b[3] = (byte) (0xff & (l >> 32));
        b[4] = (byte) (0xff & (l >> 24));
        b[5] = (byte) (0xff & (l >> 16));
        b[6] = (byte) (0xff & (l >> 8));
        b[7] = (byte) (0xff & l);
        return b;
    }

    /**
     * byte数组转double
     *
     * @param bytes        8位byte数组
     * @param littleEndian 是否是小端模式
     * @return
     */
    public static double bytesToDouble(byte[] bytes, boolean littleEndian) {
        ByteBuffer buffer = ByteBuffer.wrap(bytes, 0, 8);
        if (littleEndian) {
            // ByteBuffer.order(ByteOrder) 方法指定字节序,即大小端模式(BIG_ENDIAN/LITTLE_ENDIAN)
            // ByteBuffer 默认为大端(BIG_ENDIAN)模式
            buffer.order(ByteOrder.LITTLE_ENDIAN);
        }
        long l = buffer.getLong();
        return Double.longBitsToDouble(l);
    }

    /**
     * long转byte数组,小端模式
     *
     * @param l
     * @return
     */
    public static byte[] longToBytes_Little(long l) {
        byte b[] = new byte[8];
        b[7] = (byte) (0xff & (l >> 56));
        b[6] = (byte) (0xff & (l >> 48));
        b[5] = (byte) (0xff & (l >> 40));
        b[4] = (byte) (0xff & (l >> 32));
        b[3] = (byte) (0xff & (l >> 24));
        b[2] = (byte) (0xff & (l >> 16));
        b[1] = (byte) (0xff & (l >> 8));
        b[0] = (byte) (0xff & l);
        return b;
    }

    /**
     * long转byte数组,大端模式
     *
     * @param l
     * @return
     */
    public static byte[] longToBytes_Big(long l) {
        byte b[] = new byte[8];
        b[0] = (byte) (0xff & (l >> 56));
        b[1] = (byte) (0xff & (l >> 48));
        b[2] = (byte) (0xff & (l >> 40));
        b[3] = (byte) (0xff & (l >> 32));
        b[4] = (byte) (0xff & (l >> 24));
        b[5] = (byte) (0xff & (l >> 16));
        b[6] = (byte) (0xff & (l >> 8));
        b[7] = (byte) (0xff & l);
        return b;
    }

    /**
     * byte数组转long
     *
     * @param bytes        8位的byte数组
     * @param littleEndian 是否是小端模式
     * @return
     * @throws Exception
     */
    public static long bytesToLong(byte[] bytes, boolean littleEndian) throws Exception {
        if (bytes.length != 8) {
            throw new Exception("参数错误,无法解析。");
        }
        ByteBuffer buffer = ByteBuffer.wrap(bytes, 0, 8);
        if (littleEndian) {
            // ByteBuffer.order(ByteOrder) 方法指定字节序,即大小端模式(BIG_ENDIAN/LITTLE_ENDIAN)
            // ByteBuffer 默认为大端(BIG_ENDIAN)模式
            buffer.order(ByteOrder.LITTLE_ENDIAN);
        }
        return buffer.getLong();
    }

    /**
     * int转byte数组  ,小端
     *
     * @param num
     * @return
     */
    public static byte[] intToBytes_Little(int num) {
        byte[] result = new byte[4];
        result[0] = (byte) ((num >>> 0) & 0xff);
        result[1] = (byte) ((num >>> 8) & 0xff);
        result[2] = (byte) ((num >>> 16) & 0xff);
        result[3] = (byte) ((num >>> 24) & 0xff);
        return result;
    }

    /**
     * int转byte数组 ,大端
     *
     * @param num
     * @return
     */
    public static byte[] intToBytes_Big(int num) {
        byte[] result = new byte[4];
        result[0] = (byte) ((num >>> 24) & 0xff);
        result[1] = (byte) ((num >>> 16) & 0xff);
        result[2] = (byte) ((num >>> 8) & 0xff);
        result[3] = (byte) ((num >>> 0) & 0xff);
        return result;
    }

    /**
     * byte数组转int,小端
     *
     * @param bytes
     * @return
     */
    public static int bytesToInt_Little(byte[] bytes) {
        int result = 0;
        if (bytes.length == 4) {
            int a = (bytes[0] & 0xff) << 0;
            int b = (bytes[1] & 0xff) << 8;
            int c = (bytes[2] & 0xff) << 16;
            int d = (bytes[3] & 0xff) << 24;
            result = a | b | c | d;
        }
        return result;
    }

    /**
     * byte数组转int,大端
     *
     * @param bytes
     * @return
     */
    public static int bytesToInt_Big(byte[] bytes) {
        int result = 0;
        if (bytes.length == 4) {
            int a = (bytes[0] & 0xff) << 24;
            int b = (bytes[1] & 0xff) << 16;
            int c = (bytes[2] & 0xff) << 8;
            int d = (bytes[3] & 0xff) << 0;
            result = a | b | c | d;
        }
        return result;
    }

    /**
     * byte数组转十六进制
     *
     * @param bytes
     * @return
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder buf = new StringBuilder(bytes.length * 2);
        for (byte b : bytes) { // 使用String的format方法进行转换
            buf.append(String.format("%02x", new Integer(b & 0xff)));
        }

        return buf.toString();
    }

    /**
     * 十六进制转byte数组
     *
     * @param str
     * @return
     */
    public static byte[] hexToBytes(String str) {
        if (str == null || str.trim().equals("")) {
            return new byte[0];
        }
        byte[] bytes = new byte[str.length() / 2];
        for (int i = 0; i < str.length() / 2; i++) {
            String subStr = str.substring(i * 2, i * 2 + 2);
            bytes[i] = (byte) Integer.parseInt(subStr, 16);
        }
        return bytes;
    }

    public static void main(String[] args) throws Exception {
        int num = 100;
        // 先将int 转小端的byte[], 小端的byte[] 再转回int
        System.out.println("intToLittle: " + bytesToInt_Little(intToBytes_Little(num)));
        // 先将int 转大端的byte[], 大端的byte[] 再转回int
        System.out.println("intToBig: " + bytesToInt_Big(intToBytes_Big(num)));

        long l = 9l;
        System.out.println("longToLittle: " + bytesToLong(longToBytes_Little(l), true));
        System.out.println("longToBig: " + bytesToLong(longToBytes_Big(l), false));

        double d = 9.125d;
        System.out.println("doubleToLittle: " + bytesToDouble(doubleToBytes_Little(d), true));
        System.out.println("doubleToBig: " + bytesToDouble(doubleToBytes_Big(d), false));
        System.out.println("doubleToLittle---Hex: " + bytesToHex(doubleToBytes_Little(d)));
        System.out.println("doubleToBig---Hex: " + bytesToHex(doubleToBytes_Big(d)));
    }
}

4. 效果图

结果如下:
在这里插入图片描述

5. 参考

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.pgr照片文件解析,C++与Java存储数据差别大小端模式 的相关文章

随机推荐

  • Linux 音视频开发杂记之二-使用FFmpeg

    FFmpeg简介 FFmpeg是一套可以用来记录 转换数字音频 视频 并能将其转化为流的开源计算机程序 采用LGPL或GPL许可证 它提供了录制 转换以及流化音视频的完整解决方案 ubuntu下FFmpeg下载 编译并安装 1 基础依赖库安
  • 动态规划基础之挖金矿问题

    问题 有一个国家发现了5座金矿 每座金矿的黄金储量不同 需要参与挖掘的工人数也不同 情况如下图 金矿编号 黄金储量 需要人数 1 500 5 2 200 3 3 300 4 4 350 3 5 400 5 参与挖矿工人的总数是10人 每座金
  • 点云目标检测 国内外现状 2000字

    国内外现状近年来 点云目标检测技术受到了越来越多的关注 其中包括传统的统计学习方法和深度学习方法 由于深度学习方法的出现 点云目标检测研究取得了长足的进步 首先 深度学习方法大大提高了点云目标检测的准确率 其次 深度学习方法也大大简化了点云
  • C++:防止int32溢出--以反转数字为例

    int32溢出 在C 等语言中int类型的整数占4个字节 一般而言 而一个字节是8bit 所以int型可表示32位的整数 又因为int可以表示负数 所以int的范围是 2 31 2 31 231
  • Unity3D之UI按键绑定事件(六)

    六 通过unity系统自带接口和观察者模式绑定按键事件 UI UGUI 如何判断UI元素被点击时是鼠标哪个按键 五 中我们可以根据eventData pointerId来监听是我们按下的是鼠标左键还是右键 通过前面几部分学习我们已经实现对U
  • 字符设备驱动之异步通知

    一 应用程序主动的去查询或 read 1 查询方式 很占资源 2 中断机制 虽然有休眠 但在没有按键按下时 read 3 poll 机制 指定超时时间 以上都是 应用程序 主动去读或查询 二 异步通知 有按键按下了 驱动程序来提醒 触发 应
  • 18.函数subplot2grid():让子区跨越固定的网格布局

    文章目录 1 subplot2grid 的使用方法 2 模块gridspec中的类GridSpec的使用方法 subplot2grid 函数的rowspan和colspan参数可以让子区跨越固定的网格布局的多个行和列 实现不同的子区布局 比
  • 韩顺平 2021零基础学Java 学习笔记(1)(自用)

    目录 第 2 章 Java 概述 第 3 章 变量 第 4 章 运算符 第 5 章 程序控制结构 第 6 章 数组 排序和查找 第 7 章 面向对象编程 基础部分 第 8 章 面向对象编程 中级部分 第 2 章 Java 概述 2 1 Ja
  • Vue3 如何实现一个全局搜索框

    前言 自从学习 vue 以来 就对 vue 官网全局的 command K 调出全局关键词搜索这个功能心心念念 恰好最近项目也是需要实现一个全局搜索的功能 也正好可以正大光明的带薪学习这个功能的思路 网上的教程水平参差不齐 而恰好之前的项目
  • C++数组【修订】

    C 数组 修订 C 数组 array 是一种顺序容器sequence container 是由单一数据类型元素组成的一个有序集合 数组是用来存储一系列数据 但它往往被认为是一系列相同类型的变量 对数组元素的访问是通过下标 subscript
  • 高精度24bit 模数转化 AD7767芯片 使用总结

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家提出意见 一起讨论 PDF资料请大家网上搜索 环境 上位机 MIPS WCE6 0 1 芯片功能介绍 它是一个高精度的24bit采样SAR模数转
  • 读取pytorch.bin权重文件解读

    读取pytorch bin的权重文件实现的函数在modeling utils py之中 print load Pytorch model if state dict is None try state dict torch load res
  • 【Python】‘builtin_function_or_method‘ object is not subscriptable 错误

    Python数组初始化报错 括号问题 错误方式 inArr array ffMiles percentTags iceCream 正确方式 inArr array ffMiles percentTags iceCream
  • openjudge数据结构练习集 字符栈的实现

    字符栈的实现 查看 提交 统计 提问 总时间限制 1000ms 内存限制 1024kB 描述 本程序定义了一个有头结点的链栈 栈的数据元素类型是字符型 并实现了它的创建 入栈 出栈 获取栈顶元素 判断栈是否为空 销毁栈等操作 为了测试这些操
  • 千万不要这样使用Arrays.asList !

    作者 flyhero 微信公众号 码上实战 ID Push Code 使用Arrays asList 的原因无非是想将数组或一些元素转为集合 而你得到的集合并不一定是你想要的那个集合 而一开始asList的设计时用于打印数组而设计的 但jd
  • IDEA 查找某个 jar 包是如何被引入的

    IDEA 查找某个 jar 包是如何被引入的 方法一 我们借助 IDEA 的 maven 工具 在 maven 栏右键项目模块 选择 show Dependencies或 Ctrl Shift Alt U 这时候会展示当前模块的 jar 包
  • RT-Thread 实时操作系统(一)

    视频播放地址 https www bilibili com video BV1Cb4y1m7W5 p 2 vd source b91967c499b23106586d7aa35af46413 0 学习路线 1 RT Thread简介 2 R
  • u3d 2D Animator AnimationClip复用方案

    新做了个2D游戏 类似小时候红白机的 热血格斗 比较菜 人物2d动画就用的Animator 碰撞块的方法做的 移动 攻击等做成Clip然后通过Animator控制 发现一个人物一个Animator N个片断 然后要制作10多个不同的人物 但
  • discuz密码找回:忘记管理员密码,忘记UCENTER创始人密码

    discuz站点 忘记管理员密码或忘记ucenter管理员密码怎么办 discuz管理员密码修改 第一步进入uc后台 域名 uc server 如果uc密码忘记请继续往下看 找到用户管理里编辑管理员账号 第二步把想改的密码输入进去直接提交就
  • .pgr照片文件解析,C++与Java存储数据差别大小端模式

    1 pgr是什么 pgr文件是二进制的图像文件 可以用普通的文本文件打开 或者查看十六进制的文本信息 读取需要了解 非常重要 基本数据类型的大小端存储模式 表头Header 详细信息可参考 http www powergrep com ma