在Unity中获取图片的宽高信息

这篇具有很好参考价值的文章主要介绍了在Unity中获取图片的宽高信息。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

直接上代码,绝对好用文章来源地址https://www.toymoban.com/news/detail-552994.html

using System;
using System.IO;
using UnityEngine;

namespace ClientCode.ImgHelper
{
    /// <summary>
    /// 读取图片的宽高信息,有两种方案
    /// 方案一:利用Texture2D加载到内存中,优点就是使用简单,支持各种图片格式。缺点是,如果图片较大,会有卡顿
    /// 方案二:利用FileStream解析图片的二进制信息从而获取宽高。优点就是加载速度快,缺点是使用复杂,对每种图片类型需要分别处理
    /// 从测试结果上看,两者在加载较大的图片时(1920*1080),速度差距在7倍
    /// </summary>
    public class ImgHelper
    {
        /// <summary>
        /// 使用Texture2D获取图片宽高
        /// </summary>
        /// <param name="filePath">文件全路径</param>
        /// <returns></returns>
        public static Vector2 GetImgSize(string filePath)
        {
            var fileData = File.ReadAllBytes(filePath);
            Texture2D texture = new Texture2D(0, 0);
            texture.LoadImage(fileData);
            return new Vector2(texture.width,texture.height);
        }

        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;
        /// <summary>
        /// 使用FileStream获取图片宽高
        /// </summary>
        /// <param name="filePath">文件全路径</param>
        /// <returns></returns>
        public static Vector2 GetImgSizeFast(string filePath)
        {
            Vector2 size = Vector2.zero;
            FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            stream.Seek(0, SeekOrigin.Begin);
            byte[] 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) //文件结束
                                {
                                    break;
                                }
                            } 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();
                                        break;
                                    }
                                default: //别的段都跳过
                                         //获取段长度,直接跳过
                                    ps = stream.ReadByte() * 256;
                                    ps = stream.Position + ps + stream.ReadByte() - 2;
                                    break;
                            }
                            if (ps + 1 >= stream.Length) //文件结束
                            {
                                break;
                            }
                            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();

            return size;
        }
    }
}


到了这里,关于在Unity中获取图片的宽高信息的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Selenium - 改变窗口大小,不同机型呈现的宽高长度会不一样

    最近接触到 UI 测试,涉及到这样一个场景,改变页面大小,验证页面一个输入框默认提示符会有不同。例如:页面宽度设置成小于等于 1024,应该显示短的提示符,大于 1204 显示长的提示符。Case 在本地都是通过的,但是日常 Jenkins 运行在 Remote VM 上,尽然跟期望的不一致。

    2024年02月02日
    浏览(24)
  • Unity 获取手机地理位置信息

    在游戏的开发过程中,有时候会遇到需要获取玩家位置信息的需求,比如显示玩家所在的国家城市等。 有一下方法可以参考: 可以根据手机的地区和语言来做判断。 根据IP来判断所处的位置,阿里云啥的都有对应的接口服务。 根据GPS来判断。 以上方法都各有利弊吧,这里简

    2024年02月12日
    浏览(38)
  • 【Unity】获取视频某一帧的图片

    增加获取图片后的委托  测试:

    2024年02月15日
    浏览(49)
  • Unity微信小游戏登录授权获取用户信息

    最近需要在接微信获取用户信息的功能,在小游戏官方API中翻找资料。不得不说官方接口很多、很全,但是真的很乱而且部分遗漏。 对于不明所以的人来说,真的非常不友好。文档一堆堆的罗列下来,有些也不知道要怎么组合使用。 文档下有不少留言也是“骂骂咧咧”想必

    2024年02月02日
    浏览(48)
  • Unity日记18(刚体、获取碰撞物的信息、铰链、弹簧)

    目录 刚体 刚体 重力 isKinematic 碰撞检测 变换限制 ​编辑 碰撞  获取到碰撞物的实体,输出它的某个信息。  碰撞和触发器的区别 铰链 锚点和轴 弹簧组件 固定关节组件 定制摩擦力面 添加了好像不能禁用。 重力,顾名思义。 禁用重力,不受重力影响。当有物体撞击,猜测

    2024年02月07日
    浏览(32)
  • Unity 编辑器工具之批量设置图片压缩

    一个简单的工具,对Unity下的图片做批量压缩处理,主要有以下功能: 自动取消 \\\"Generte Mip Maps\\\" 勾选; 针对文件夹批量自动(或手动选择压缩格式)设置图片压缩并自动保存; 单个图片文件的压缩设置; 使用方法,右键单张图片(或者包含图片的文件夹) 会打开一个设置窗口 如下,窗口里会

    2024年02月10日
    浏览(36)
  • Unity C# 之 Http 获取网页的 html 数据,并去掉 html 格式等相关信息

    目录 Unity C# 之 Http 获取网页的 html 数据,并去掉 html 格式等相关信息 一、简单介绍 二、实现原理 三、注意事项 四、效果预览  五、关键代码 Unity中的一些知识点整理。 本节简单介绍在Unity开发中的,使用 HttpClient,获取指定网页的相关信息,然后进行数据清洗,去掉html 格

    2024年02月12日
    浏览(29)
  • Unity聊天对话框内容自适应宽高(无需代码辅助布局,不添加冗余组件)

    聊天框是Unity开发中常见的功能,不过要做好聊天框的自适应需要一些布局方面的知识。 大致效果如图: 1.文字内容不足最大宽度时,文字背景和文字宽度吻合 2.文字内容超过最大宽度时,自动增加高度 3.右边聊天框跟随聊天面板最右侧对齐 4.文字内容的最大限宽跟随整个聊

    2024年02月04日
    浏览(37)
  • 【Unity 框架】QFramework v1.0 使用指南 工具篇:13. 其他事件工具 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏

    QFramework 除了支持了 TypeEventSystem、EasyEvent 还支持了 EnumEventSystem、StringEventSystem。 EnumEventSystem 前身是 老版本 QFramework 的 QEventSystem StringEventSystem 的前身是,老版本的 MsgDispatcher TypeEventSystem: 事件体定义简洁 比较适合用于设计框架 支持 struct 获得较好内存性能 使用反射,CPU

    2023年04月17日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包