解析图片文件格式

news/2024/7/21 7:04:07 标签: 音视频, 图像处理

图片文件幻数

在这里插入图片描述

关于JPEG格式

二进制形式打开文件,文件开始字节为FF D8,文件结束两字节为FF D9
JPEG 文件有两种不同的元数据格式:JFIF 和 EXIF。
JFIF 以 ff d8 ff e0 开头,EXIF 以 ff d8 ff e1 开头。

代码示例

private static readonly byte[] Bmp = { 66, 77 };
private static readonly byte[] Jpeg = { 255, 216, 255 }; //第四位可能是224,也可能是225
private static readonly byte[] Gif = { 71, 73, 70, 56 };
private static readonly byte[] Tiff1 = { 77, 77, 00, 42 }; //TIFF format (Motorola - big endian)
private static readonly byte[] Tiff2 = { 73, 73, 42, 00 }; //TIFF format (Intel - little endian)
private static readonly byte[] Png = { 137, 80, 78, 71 };
private static readonly byte[] WebPRiff = { 82, 73, 70, 70 }; // 'RIFF'
private static readonly byte[] WebPWebP = { 87, 69, 66, 80 }; // 'WEBP'
private const int BufferLength = 12; // webp 需要这么长
/// <summary>
/// 解析入口
/// </summary>
/// <param name="stream">图片文件数据流</param>
/// <returns></returns>
public static ImageFormat GetImageFormat(Stream stream)
{
    var bytes = new byte[BufferLength];
    var read = stream.Read(bytes, 0, bytes.Length);
    return read < BufferLength ? ImageFormat.Unknown : GetImageFormat(bytes);
}

/// <summary>
/// 获取文件格式类型
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static ImageFormat GetImageFormat(byte[] bytes)
{
    if (bytes.Length < BufferLength)
        return ImageFormat.Unknown;

    if (bytes.Take(Bmp.Length).SequenceEqual(Bmp))
        return ImageFormat.Bmp;
    if (bytes.Take(Jpeg.Length).SequenceEqual(Jpeg))
        return ImageFormat.Jpeg;
    if (bytes.Take(Gif.Length).SequenceEqual(Gif))
        return ImageFormat.Gif;
    if (bytes.Take(Tiff1.Length).SequenceEqual(Tiff1)
        || bytes.Take(Tiff2.Length).SequenceEqual(Tiff2))
        return ImageFormat.Tiff;
    if (bytes.Take(Png.Length).SequenceEqual(Png))
        return ImageFormat.Png;
    if (bytes.Take(WebPRiff.Length).SequenceEqual(WebPRiff)
        && bytes.Skip(8).Take(WebPWebP.Length).SequenceEqual(WebPWebP))
        return ImageFormat.WebP;

    return ImageFormat.Unknown;
}

源码传送门


http://www.niftyadmin.cn/n/5076561.html

相关文章

【思维构造】Effects of Anti Pimples—CF1877D

Effects of Anti Pimples—CF1877D 难度大概在1500~1600。 这个D题比C题简单&#xff0c;以后遇到做不出来的题要及时换题。 题目不难&#xff0c;就不写思路了。 C o d e Code Code #include <bits/stdc.h> #define int long long #define sz(a) ((int)a.size()) #def…

【智慧燃气】智慧燃气解决方案总体概述--终端层、网络层

关键词&#xff1a;智慧燃气、智慧燃气系统、智慧燃气平台、智慧燃气解决方案、智慧燃气应用、智能燃气 智慧燃气解决方案是基于物联网、大数据、云计算、移动互联网等先进技术&#xff0c;结合燃气行业特征&#xff0c;通过智能设备全面感知企业生产、环境、状态等信息的全方…

RK3588开发笔记-MIPI-CSI接口视频解码芯片XS9922B调试

目录 前言 一、RK3588 MIPI接口介绍 二、xs9922B视频解码芯片介绍 三、原理图连接

【kubernetes】带你了解k8s中PV和PVC的由来

文章目录 1 为什么需要卷(Volume)2 卷的挂载2.1 k8s集群中可以直接使用2.2 需要额外的存储组件2.3 公有云 2 PV(Persistent Volume)3 SC(Storage Class) 和 PVC(Persistent Volume Claim)4 总结 1 为什么需要卷(Volume) Pod是由一个或者多个容器组成的&#xff0c;在启动Pod中…

MySQL运维—从零到放弃

1. 日志 1.1 错误日志 错误日志是 MySQL 中最重要的日志之一&#xff0c;它记录了当 mysqld 启动和停止时&#xff0c;以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时&#xff0c;建议首先查看此日志。 该日志是默认开启的…

java学习--day23(线程池)

1.线程池Pool 线程池一个容纳了多个线程的容器&#xff0c;其中的线程可以反复的使用。省去了频繁创建线程的对象的操作&#xff0c;无需反复创建线程而消耗更多的资源 在 Java 语言中&#xff0c;并发编程都是通过创建线程池来实现的&#xff0c;而线程池的创建方式也有很多种…

Windows实现到WSL的免密登录

为了从Windows实现到WSL的免密登录&#xff0c;我们可以使用SSH的公钥身份验证。这涉及到在Windows上生成SSH密钥对&#xff0c;并将公钥放入WSL的authorized_keys文件中。 具体步骤如下&#xff1a; 在Windows中生成SSH密钥对 (如果还没有)&#xff1a; 如果已经有OpenSSH fo…

es6.x和es7.x如何创建索引?

一、es6.x {"settings": {"number_of_shards": "2","number_of_replicas": "2","max_result_window": 100000},"mappings": {"doc": {"dynamic": "strict","prope…