开发者

ActionScript 3 Read JPEG quality

I am developing image uploader for Flash 10. Is there a way to read jp开发者_如何转开发eg quality of the browsed images.


Unfortunately, it can't be done directly:

The quality factor is not stored directly in the JPEG file, so you cannot read the quality factor from the file. (from: Microsoft support pages...)

In more detail:

The quantization table that was used to compress an image is stored in the JFIF header, but the JPEG Quality Factor that was used to generate the quantization table is not stored along with the image and hence the original JPEG Quality Factor is lost. (from: JPEG Compression Metrics as a Quality Aware Image Transcoding, by Surendar Chandra and Carla Schlatter Ellis)

The above quote is from a paper which discusses ways to estimate the level of compression (by examining the quantization tables used in the image), but it doesn't look easy to implement: there's an example here which is part of the Image Magick codebase, but it's written in C.

Image Magick has been ported to Haxe, which can be complied into Flash code, so conceivably you could get something working, but I'm afraid it's beyond my skills to explain how!


EDIT: just found a similar question on SuperUser, which also mentions Image Magick.


EDIT: you might also be interested in the answers to this question, which asked how to get the size of an image without loading the whole file (good for dealing with images bigger than Flash can handle).


I have used the libjpeg to finish this job, maybe you can refer to my code

#include <stdio.h>
#include <math.h>

#include "jpeglib.h"
#include <setjmp.h>

static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
  16,  11,  10,  16,  24,  40,  51,  61,
  12,  12,  14,  19,  26,  58,  60,  55,
  14,  13,  16,  24,  40,  57,  69,  56,
  14,  17,  22,  29,  51,  87,  80,  62,
  18,  22,  37,  56,  68, 109, 103,  77,
  24,  35,  55,  64,  81, 104, 113,  92,
  49,  64,  78,  87, 103, 121, 120, 101,
  72,  92,  95,  98, 112, 100, 103,  99
};

int ReadJpegQuality(const char *filename)
{
  FILE * infile = fopen(filename, "rb");
  fseek(infile,0,SEEK_END);
  size_t sz = ftell(infile);
  fseek(infile,0,SEEK_SET);
  unsigned char* buffer = new unsigned char[sz];
  fread(buffer,1,sz,infile);
  fclose(infile);
  struct jpeg_decompress_struct cinfo;
  struct jpeg_error_mgr jerr;
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_decompress(&cinfo);
  jpeg_mem_src(&cinfo,(unsigned char*)buffer,sz);
  jpeg_read_header(&cinfo, TRUE);
  int tmp_quality = 0;
  int linear_quality = 0;
  const int aver_times = 3;
  int times = 0;
  int aver_quality = 0;
  for(int i=0;i<DCTSIZE2;i++)
  {
    long temp = cinfo.quant_tbl_ptrs[0]->quantval[i];
    if(temp<32767L&&temp>0)
    {
      linear_quality = ceil((float)(temp*100L - 50L)/std_luminance_quant_tbl[i]);
      if(linear_quality==1) tmp_quality = 1;
      else if(linear_quality==100) tmp_quality = 100;
      else if(linear_quality>100)
      {
        tmp_quality = ceil((float)5000/linear_quality);
      }
      else
      {
        tmp_quality = 100 - ceil((float)linear_quality/2);
      }
      aver_quality += tmp_quality;
      if(aver_times==++times)
      {
        aver_quality /= aver_times;
        break;
      } 
    }
  }
  jpeg_destroy_decompress(&cinfo);
  return aver_quality;
}

int main(int argc,char** argv)
{
  printf("quality: %d\n",ReadJpegQuality("test1.jpg"));
  return 0; 
}

this method is using the libjpeg to read jpg file's quantization table,then use the quantization table calculate the quality arguments.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜