Unity 使用IO流获取PNG/JPG/GIF/BMP的宽高【转】
原文链接:https://blog.csdn.net/flj135792468/article/details/107963280?utm_medium=distribute.pc_relevant.none-task-blog-baidulandingword-8&spm=1001.2101.3001.4242
读取图片流前8个字节
Png图片 8字节:89 50 4E 47 0D 0A 1A 0A = [1]:P[2]:N[3]:G
Jpg图片 2字节:FF D8
Gif图片 6字节:47 49 46 38 39|37 61 = G I F 8 9 7 a
Bmp图片 2字节:42 4D
根据字节判断所属是什么类型
public class FileUtility
{
public enum ImageType
{
Null,
Png,
Jpg,
Gif,
Bmp
}
/// <summary>
/// 获取图片格式
/// </summary>
private static ImageType GetImageType(byte[] bytes)
{
byte[] header = new byte[8];
Array.Copy(bytes, header, header.Length);
ImageType type = ImageType.Null;
//读取图片文件头8个字节
//Png图片 8字节:89 50 4E 47 0D 0A 1A 0A = [1]:P[2]:N[3]:G
if (header[0] == 0x89 && header[1] == 0x50 && header[2] == 0x4E && header[3] == 0x47 &&
header[4] == 0x0D && header[5] == 0x0A && header[6] == 0x1A && header[7] == 0x0A)
{
type = ImageType.Png;
}
//Jpg图片 2字节:FF D8
else if (header[0] == 0xFF && header[1] == 0xD8)
{
type = ImageType.Jpg;
}
//Gif图片 6字节:47 49 46 38 39|37 61 = GIF897a
else if (header[0] == 0x47 && header[1] == 0x49 && header[2] == 0x46 && header[3] == 0x38 &&
(header[4] == 0x39 || header[4] == 0x37) && header[5] == 0x61)
{
type = ImageType.Gif;
}
//Bmp图片 2字节:42 4D
else if (header[0] == 0x42 && header[1] == 0x4D)
{
type = ImageType.Bmp;
}
return type;
}
private static byte[] _header = null;
private static byte[] _buffer = null;
public static void FileInfo(string filePath, out byte[] bytes, out Vector2 size)
{
size = Vector2.zero;
FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
stream.Seek(0, SeekOrigin.Begin);
bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
ImageType imageType = GetImageType(bytes);
switch (imageType)
{
case ImageType.Png:
{
stream.Seek(0, SeekOrigin.Begin);
_header = new byte[8];
stream.Read(_header, 0, 8);
stream.Seek(8, SeekOrigin.Current);
_buffer = new byte[8];
stream.Read(_buffer, 0, _buffer.Length);
Array.Reverse(_buffer, 0, 4);
Array.Reverse(_buffer, 4, 4);
size.x = BitConverter.ToInt32(_buffer, 0);
size.y = BitConverter.ToInt32(_buffer, 4);
}
break;
case ImageType.Jpg:
{
stream.Seek(0, SeekOrigin.Begin);
_header = new byte[2];
stream.Read(_header, 0, 2);
//段类型
int type = -1;
int ff = -1;
//记录当前读取的位置
long ps = 0;
//逐个遍历所以段,查找SOFO段
do
{
do
{
//每个新段的开始标识为oxff,查找下一个新段
ff = stream.ReadByte();
if (ff < 0) //文件结束
{
return;
}
} while (ff != 0xff);
do
{
//段与段之间有一个或多个oxff间隔,跳过这些oxff之后的字节为段标识
type = stream.ReadByte();
} while (type == 0xff);
//记录当前位置
ps = stream.Position;
switch (type)
{
case 0x00:
case 0x01:
case 0xD0:
case 0xD1:
case 0xD2:
case 0xD3:
case 0xD4:
case 0xD5:
case 0xD6:
case 0xD7:
break;
case 0xc0: //SOF0段(图像基本信息)
case 0xc2: //JFIF格式的 SOF0段
{
//找到SOFO段,解析宽度和高度信息
//跳过2个自己长度信息和1个字节的精度信息
stream.Seek(3, SeekOrigin.Current);
//高度 占2字节 低位高位互换
size.y = stream.ReadByte() * 256;
size.y += stream.ReadByte();
//宽度 占2字节 低位高位互换
size.x = stream.ReadByte() * 256;
size.x += stream.ReadByte();
return;
}
default: //别的段都跳过
//获取段长度,直接跳过
ps = stream.ReadByte() * 256;
ps = stream.Position + ps + stream.ReadByte() - 2;
break;
}
if (ps + 1 >= stream.Length) //文件结束
{
return;
}
stream.Position = ps; //移动指针
} while (type != 0xda); // 扫描行开始
}
break;
case ImageType.Gif:
{
stream.Seek(0, SeekOrigin.Begin);
_header = new byte[6];
stream.Read(_header, 0, 6);
_buffer = new byte[4];
stream.Read(_buffer, 0, _buffer.Length);
size.x = BitConverter.ToInt16(_buffer, 0);
size.y = BitConverter.ToInt16(_buffer, 2);
}
break;
case ImageType.Bmp:
{
stream.Seek(0, SeekOrigin.Begin);
_header = new byte[2];
stream.Read(_header, 0, 2);
//跳过16个字节
stream.Seek(16, SeekOrigin.Current);
//bmp图片的宽度信息保存在第 18-21位 4字节
//bmp图片的高度度信息保存在第 22-25位 4字节
_buffer = new byte[8];
stream.Read(_buffer, 0, _buffer.Length);
size.x = BitConverter.ToInt32(_buffer, 0);
size.y = BitConverter.ToInt32(_buffer, 4);
}
break;
default:
break;
}
stream.Close();
stream.Dispose();
}
}
Unity 使用IO流获取PNG/JPG/GIF/BMP的宽高【转】的更多相关文章
- IO流-获取指定目录下文件夹和文件对象【File类】
一.运用File类实现获取指定目录下文件夹和文件对象 1.File类 2.方法: 获取文件绝对路径 :getAbsolutePath 案例: import java.io.File; /** * 获取 ...
- Android如何在初始化的时候获取加载的布局的宽高
在自定义ListView中,需要将下拉刷新的View在初始化的时候设置padding隐藏起来,这时就要在初始化的时候获得要加载的布局View的高度. private View headView; he ...
- js获取图片信息(二)-----js获取img的height、width宽高值为0
首先,创建一个图片对象: var oImg= new Image(); oImg.src = "apple.jpg"; 然后我们打印一下图片的信息: console.log(oIm ...
- [转]ASP.NET如何获取上传图片尺寸(是指宽高)
1.采用客户端javascript可以取得图片大小 <input id="FileUpload" type="file" size="27&qu ...
- JavaScript(获取或设置html元素的宽,高,坐标),确定和判断鼠标是否在元素内部,二级导航菜单鼠标离开样式问题解决
设置: document.getElementById('id').style.width=value document.getElementById('id').style.height=va ...
- Java IO流题库
一. 填空题 Java IO流可以分为 节点流 和处理流两大类,其中前者处于IO操作的第一线,所有操作必须通过他们进行. 输入流的唯一目的是提供通往数据的通道,程序可以通过这个通道读取数 ...
- JavaEE基础(二十一)/IO流
1.IO流(字符流FileReader) 1.字符流是什么 字符流是可以直接读写字符的IO流 字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再写出. 2 ...
- IO流作业
IO流作业 一. 填空题 Java IO流可以分为 字节流 和处理流两大类,其中前者处于IO操作的第一线,所有操作必须通过他们进行. 输入流的唯一目的是提供通往数据的通道 ...
- day21<IO流+&FIle递归>
IO流(字符流FileReader) IO流(字符流FileWriter) IO流(字符流的拷贝) IO流(什么情况下使用字符流) IO流(字符流是否可以拷贝非纯文本的文件) IO流(自定义字符数组的 ...
- Java 基础(四)| IO 流之使用文件流的正确姿势
为跳槽面试做准备,今天开始进入 Java 基础的复习.希望基础不好的同学看完这篇文章,能掌握泛型,而基础好的同学权当复习,希望看完这篇文章能够起一点你的青涩记忆. 一.什么是 IO 流? 想象一个场景 ...
随机推荐
- Python3+Selenium3自动化测试-(七)
在实际定位元素的过程中,发现有一种情况让人很是恼火,根据xpath路径定位,感觉像是没错哦,但是执行时就来一个报错信息--为什么呢? 多表单切换 例如我们登录网易邮箱时就会发现,定位登录框时,一个嵌套 ...
- 阿里百秀后台管理项目笔记 ---- Day02
来吧展示: step1: 动态获取用户头像信息 引入 jquery.js 文件 <script src="/static/assets/vendors/jquery/jquery.js ...
- 【Oculus Interaction SDK】(三)限制可操作物体的移动 / 旋转
前言 这篇文章是[Oculus Interaction SDK]系列的一部分,如果发现有对不上的对方,可以回去翻看我之前发布的文章,或在评论区留言.如果文章的内容已经不适用于新版本了,也可以直接联系我 ...
- Nacos注册中心 (介绍与配置)
Nacos注册中心 和Euraka一样都是注册中心,但Nacos不需要注册Nacos,因为阿里巴巴已经注册在好了.只需要下载安装后打开即可 Windows安装 开发阶段采用单机安装即可 1.1.下载安 ...
- selenium注入js代码
from selenium import webdriver from selenium.webdriver import ActionChains import time dr = webdrive ...
- Spacemacs换源无效果
我改了发现没用,找了好久问题,才发现变量名改了,以前修改源是configuration-layer–elpa-archives这个变量,现在改为configuration-layer-elpa-arc ...
- jquery(三:jquery的动画)
动画 一:1.显示 show() 参数:1.代表动画执行的时长,毫秒数,也可以是代表时长的字符串 fast normal slow 2.代表方法执行完毕的回调函数 默认的是:normal $(func ...
- JumpServer(v2.28.6) 堡垒机常见问题
JumpServer 各组件查询日志方法 # 默认持久化目录 /data/jumpserver ls -al /data/jumpserver/core/logs ls -al /data/jumps ...
- CSP2022 S游记
9.26:开坑. 没报 J 组主要是因为 J 比较垃圾,去抢小朋友的一等没什么意思. 初赛 刚拿到试卷就直接懵了,这 tm 是给人做的题?宇宙射线是什么奇妙东西,还有基数排序我根本不会啊,这个阅读程序 ...
- Postgres14.4(Docker安装)
Postgres14.4(Docker安装) 一,Docker拉取镜像 docker pull postgres:14.4 #检查镜像是否拉取成功 docker images | grep postg ...