b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

JPEG文件分析和无损压缩实践

电脑杂谈  发布时间:2020-05-12 01:29:15  来源:网络整理

jpeg如何压缩_jpeg格式压缩_jpeg图片压缩

JPEG格式的图片是最常见的图片格式. 它使用有损压缩算法,该算法可处理图片量与质量之间的关系,并且更有利于传播. 因此,JPEG也是最常见的网络标准文件格式. . 使用JPEG格式压缩的图像文件通常也称为JPEG文件,最常用的扩展名格式是.jpg. 但是JEPG标准只是一些压缩方法的描述. 它没有指定文件格式. 为了保存和传输文件,发明了一些文件格式标准. 最常见的文件格式是JPEG / Exif和JPEG / JFIF. JPEG和JIFF / Exif之间的关系类似于unicode和utf-8,一种用于编码,另一种用于存储.

jpeg图片压缩_jpeg格式压缩_jpeg如何压缩

JPEG文件通常使用有损压缩. 所谓有损压缩是指JPEG使用破坏性数据压缩来减小图片大小并促进传输. 我们最常使用Photoshop选择图片质量. 质量越低,图片量越小,质量越高jpeg格式压缩,图片量越大. 在Web应用程序中,经常需要压缩图片以达到减少宽带使用和加快页面显示的目的. 一些测试软件还经常提供有关网页图片大小的建议,例如thinkwithgoogle. 人们经常告诉我们,最简单的方法是使用phototop将图片调整为相应的尺寸(“另存为网络”格式),然后选择适当的质量. 因此,使用Photoshop压缩后,您可以真正坐下来放松一下,并且图片没有其他优化的余地. 要了解此问题,我们需要分析JPEG文件的存储格式.

jpeg格式压缩_jpeg如何压缩_jpeg图片压缩

JPEG文件包含多个数据段(段),每个段包含不同类型的数据,数据段由两个字节分开,称为标记,标记以0xff开头,后跟一个字节以表示不同的类型标记. 一些标记只有一个两个字节,其他的则包括数据长度和数据. 具体结构如下:

jpeg如何压缩_jpeg图片压缩_jpeg格式压缩

JEPG的元数据存储在APPn部分中jpeg格式压缩,注释数据存储在com部分中. 一些制造商可能会在APPn部分中添加自己的数据,例如相机型号和GPS信息.

jpeg格式压缩_jpeg图片压缩_jpeg如何压缩

com是图片的注释信息,APPn是应用程序存储的相关信息. 这些信息对图片本身没有影响,可以将其全部删除. 经过PS处理后,我们使用二进制Open拍了一张照片,发现了以下内容:

显然,此信息对图像无用,可以删除,删除后不会影响图像质量.

PHP

<?php
class JPEG{
    //JPEG Metadata Structure
    private $markerkey=array("soi"=>0xd8,"sof0"=>0xc0,"sof2"=>0xc2,"dht"=>0x,"dqt"=>0xdb,"dri"=>0xdd,"sos"=>0xda,"rst"=>array(0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7),"app"=>array(0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef),"com"=>0xfe,"eoi"=>0xd9);
    private $markerdata=array();
    private $ImageScan;
    private $Image;
    private $PosPointer;
    private $ImageSize;
    public function __construct($argument){
        if(file_exists($argument)){
            $this->Image = fopen($argument,"rb+");
            $this->ImageSize= filesize($argument);
        }else{
            die("File Not Exists");
        }
        if($this->GetByte(2)!==0xd8ff){
            die("Not a JPEG Image");
        }
        $this->Parse();
    }
    public function GetByte($len){
        if(feof($this->Image)) return NULL;
        $tmp =  fread($this->Image,$len);
        $tmp2=array();
        $this->PosPointer=ftell($this->Image);
        if($len==1){
            $tmp2=unpack("C",$tmp);
        }else if($len==2){
            $tmp2=unpack("S",$tmp);
        }else if($len==4){
            $tmp2=unpack("L",$tmp);
        }else{
            $tmp2[1]=$tmp;
        }
        return $tmp2[1];
    }
    public function GetMarkerData(){
        $buffer="";
        foreach($this->markerdata as $d){
            foreach($d as $c){
                $buffer.=$c;
            }
        }
        return $buffer;
    }
    public function get_marker($byte){
        foreach($this->markerkey as $meta=>$bit){
            if(is_array($bit)){
                foreach($bit as $b){
                    if($byte == $b) return $meta;
                }
            }
            if($byte == $bit) return $meta;
        }
        return NULL;
    }
    public function compress(){
        //Remove Com Marker
        $this->markerdata['com']=array();
        //Remove App Marker
        $this->markerdata['app']=array();
    }
    public function Parse(){
        while(($byte=$this->GetByte(1))!==NULL){
            $nxtbyte = @$this->GetByte(1);
            if($byte == 0xff){
                $marker = $this->get_marker($nxtbyte);
                //Variable Size Marker
                if($marker == "sof" || $marker == "sof2" || $marker == "dht" || $marker == "dqt" || $marker == "sof0" || $marker == "app" || $marker == "com"){
                    $offset1= $this->GetByte(1);
                    $offset2 = $this->GetByte(1);
                    $len = $offset1*256+$offset2;
                    $data = $this->GetByte($len-2);
                    //full data include marker and length
                    $fulldata = pack("C",0xff).pack("C",$nxtbyte).pack("C",$offset1).pack("C",$offset2).$data;
                    $this->markerdata[$marker][]= $fulldata;
                }else if($marker=="dri"){
                    //pass
                }else if($marker=="rst"){
                    //pass
                }else if($marker=="sos"){
                    //SOS Segment
                    $len = $this->ImageSize-$this->PosPointer-1;
                    $this->ImageScan =  pack("C",0xff). pack("C",0xda).$this->GetByte($len);
                }
            }
        }
    }
    public function GetImageBin(){
        return pack("S",0xd8ff).$this->GetMarkerData().$this->ImageScan.pack("S",0xd9ff);
    }
    public function Storage(){
        fseek($this->Image,0);
        fwrite($this->Image,$this->GetImageBin());
    }
    public function __destruct(){
        fclose($this->Image);
    }
}
$image = new JPEG("test.jpg");
$image->compress();
$image->Storage();

JPEG文件中的元数据Exif文件格式的说明文件布局


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/tongxinshuyu/article-206931-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 赵雪平
        赵雪平

        如果连自己的领海都能让人随便入侵

      • 明芷
        明芷

        另一半利息在国内开家公司

      • 吕洞宾
        吕洞宾

        再个地方政府保护当地企业也很正常

      每日福利
      热点图片
      拼命载入中...