ExifReader β
もう力尽きました…
サブ情報どこにあんの・・・・?
/**
* Copyright zahir ( http://wonderfl.net/user/zahir )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/rtQ7
*/
/*
もう力尽きました…
サブ情報どこにあんの・・・・?
*/
package{
import com.bit101.components.Label;
import com.bit101.components.ProgressBar;
import com.bit101.components.PushButton;
import flash.display.Graphics;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.ProgressEvent;
import flash.filters.GlowFilter;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.text.TextField;
import flash.utils.ByteArray;
import flash.utils.IDataInput;
[SWF(width="465", height="465", backgroundColor="0xFFFFFF")]
public class ExifReader extends Sprite{
private var btn:PushButton;
private var txt:MyText;
private var jpg:JPG;
private var fr:FileReference;
private var fileFilter:Array = [ new FileFilter("load jpg image", "*.jpg;*.jpeg;*.JPG") ];
private var progressBar:ProgressBar;
private var loader:Loader;
public function ExifReader(){
var lbl:Label = new Label(this, 235, 0, "Exif Reader");
lbl.scaleX = lbl.scaleY = 2;
btn = new PushButton(this, 10,8, "load jpg", startLoad);
txt = new MyText(this, 220, 420, 10, 35);
addChild((loader = new Loader()));
loader.x = 240;
loader.filters = [ new GlowFilter(0xFFFFFF, 1, 2,2, 8) ];
progressBar = new ProgressBar(this);
progressBar.visible = false;
progressBar.x = (465 - progressBar.width) >>1;
progressBar.y = (465 - progressBar.height) >> 1;
progressBar.filters = [ new GlowFilter(0x666666,0.2,8,8) ];
drawBackground();
}
private function startLoad(e:MouseEvent):void{
fr = new FileReference();
fr.addEventListener( Event.SELECT, onSelect );
fr.browse( fileFilter );
}
private function onSelect(e:Event):void{
fr.removeEventListener( Event.SELECT, onSelect );
fr.addEventListener(Event.COMPLETE, onLoadComp);
fr.addEventListener(ProgressEvent.PROGRESS, onProgress);
progressBar.visible = true;
fr.load();
}
private function onProgress(e:ProgressEvent):void{
progressBar.value = e.bytesLoaded;
progressBar.maximum = e.bytesTotal;
}
private function onLoadComp(e:Event):void{
fr.removeEventListener(Event.COMPLETE, onLoadComp);
fr.removeEventListener(ProgressEvent.PROGRESS, onProgress);
progressBar.visible = false;
if( check(fr.data) ){
imgLoad();
readExif();
}else{
txt.text = "jpgでないか、サイズオーバーです";
}
}
private function imgLoad():void{
fr.data.position = 0;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
progressBar.visible = true;
loader.loadBytes( fr.data );
}
private function onComplete(e:Event):void{
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgress);
progressBar.visible = false;
loader.width = 215;
loader.scaleY = loader.scaleX;
loader.y = (465 - loader.height) >> 1;
}
private function readExif():void{
var arr:Array;
if(jpg && jpg.exif && jpg.exif.tags){
arr = jpg.exif.tags;
}else return;
var str:String = "";
for(var i:int = 0, len:int =arr.length; i<len ;i++){
var tag:ExifTag = arr[i];
str +=tag.toString() + "\n";
}
txt.appendText( str );
}
private function check( input:IDataInput ):Boolean{
jpg = new JPG(input);
txt.text = "w :: " + jpg.width + " h :: " + jpg.height + "\n\n";
return jpg.check( true );
}
private function drawBackground():void{
var fill:uint = 0x111111;
var line:uint = 0x222222;
var g:Graphics = this.graphics;
g.beginFill( fill );
g.drawRect(0,0,465,465);
g.endFill();
var n:int = 0;
g.lineStyle( 2, line);
while(n < 950){
g.moveTo( n, 0);
g.lineTo(0,n);
n+= 10;
}
}
}
}
import flash.text.TextField;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.utils.IDataInput;
import flash.utils.ByteArray;
import mx.events.IndexChangedEvent;
import flash.utils.Endian;
class JPG{
static public const SOI:uint = 0xFFD8; // Start on Image
static public const APP0:uint = 0xFFE0; // 解像度情報等
static public const APPX:uint = 0xFFED;
static public const DQT:uint = 0xFFDB; // テーブル定義
static public const DHT:uint = 0xFFC4;
static public const SOF0:uint = 0xFFC0;
static public const SOF1:uint = 0xFFF0;
static public const DRI:uint = 0xFFF0;
static public const SOS:uint = 0xFFF0; // Start of Scan
static public const EOI:uint = 0xFFF0; // End of Image
private var _check:Boolean = false;
private var _width:int;
private var _height:int;
private var _version:Number;
private var width_dpi:int;
private var height_dpi:int;
private var _exif:Exif;
public function JPG( input:IDataInput ){
var ba:ByteArray = new ByteArray();
input.readBytes( ba );
ba.position = 0;
if( ba.readUnsignedShort() !== JPG.SOI ) return;
else _check = true;
while(ba.bytesAvailable){
var marker:uint = ba.readUnsignedShort();
var app:ByteArray = new ByteArray();
var len:uint = 0;
if( marker >= JPG.APP0 && marker <= JPG.APPX ){
len = ba.readUnsignedShort() - 2;
ba.readBytes( app, 0, len);
readAPP( app );
}else if( marker == JPG.SOF0){
len = ba.readUnsignedShort() - 2;
ba.readBytes( app, 0, len);
readSOF0( app );
}else if( marker == JPG.EOI){
break;
}else{
len = ba.readUnsignedShort() - 2;
ba.position += len;
};
}
}
private function readAPP(data:ByteArray):void{
var mark:String = data.readUTFBytes(4).toLocaleLowerCase();
if(mark == "jfif"){
data.position = 5;
readJFIF( data );
}else if( mark == "exif"){
data.position = 6;
readExif( data );
}
}
private function readJFIF( data:ByteArray ):void{
_version = data.readUnsignedShort() * 0.01;
data.position += 1;
_width = data.readUnsignedShort();
_height = data.readUnsignedShort();
}
private function readExif( data:ByteArray ):void{
_exif = new Exif();
_exif.setData( data );
}
private function readSOF0( data:ByteArray ):void{
data.position = 1;
_width = data.readUnsignedShort();
_height = data.readUnsignedShort();
}
public function check( size:Boolean = true):Boolean{
if( !_check ) return false;
if( !size ) return _check;
if( totalPixel >= 0xFFFFFF) return false;
return true;
}
public function get exif():Exif{
return _exif;
}
public function get totalPixel():uint{
return _width * _height;
}
public function get width():int{ return _width; }
public function get height():int{ return _height; }
}
class Exif{
public var tags:Array;
public function Exif():void{}
public function setData(data:ByteArray):void{
var ba:ByteArray = new ByteArray();
data.readBytes( ba );
var tiff_header:String = ba.readUTFBytes( 2 );
if( tiff_header == "MM"){
ba.endian = Endian.BIG_ENDIAN;
}else if( tiff_header == "II" ){
ba.endian = Endian.LITTLE_ENDIAN;
}
ba.position = 4;
ba.position = ba.readUnsignedInt();
readTAG( ba );
}
private function readTAG( data:ByteArray ):void{
var num:int = data.readUnsignedShort();
if(num < 1) return;
tags = [];
var ba:ByteArray = new ByteArray();
data.readBytes( ba, 0, 12 * num);
ba.endian = data.endian;
var offset:uint = data.position;
for(var i:int = 0; i< num; i++){
ba.position = 12*i;
var tag:ExifTag = new ExifTag();
tags[i] = tag;
tag.tag = ba.readUnsignedShort();
tag.propertyType = ba.readUnsignedShort();
tag.propertyNum = ba.readUnsignedInt();
tag.propertyOffset = ba.readUnsignedInt();
var sub:ByteArray;
if(tag.useBytes > 4){
data.position = tag.propertyOffset;
sub= new ByteArray();
data.readBytes( sub, 0, tag.useBytes);
sub.endian = ba.endian;
tag.data= sub;
}else {
ba.position -= 4;
sub= new ByteArray();
ba.readBytes( sub, 0, 4);
sub.endian = ba.endian;
tag.data = sub;
}
}
}
}
class ExifTag{
static public const TYPE_NAME:Array = ["","BYTE","ASCII","SHORT","LONG","RATIONAL","","UNDEFINED","","SLONG","SRATIONAL"];
static public const TYPE_USE_BYTE:Array = [0,1,1,2,4,8,0,1,0,4,8];
public var tag:uint;
private var _property:*;
public var propertyType:uint
public var propertyNum:uint;
public var propertyOffset:uint;
public var data:ByteArray;
public function get property():*{
if(!data)return;
if( !_property){
var i:int;
switch(ExifTag.TYPE_NAME[ propertyType ]){
case "BYTE" : break;
case "ASCII" :
data.position = 0;
_property = data.readMultiByte( useBytes, "us-ascii");
break;
case "SHORT" :
data.position = 0;
_property = 0;
for(i=0;i<propertyNum;i++){
_property += data.readUnsignedShort();
}break;
case "LONG" :
data.position = 0;
_property = 0;
for(i=0;i<propertyNum;i++){
_property += data.readUnsignedInt();
}break;
case "RATIONAL" :
data.position = 0;
_property = 0;
for(i=0;i<propertyNum;i++){
if( tag == 282 || tag == 283){
_property = data.readUnsignedInt() + "/" + data.readUnsignedInt();
}else{
_property += data.readUnsignedInt();
_property += data.readUnsignedInt();
}
}break;
case "UNDEFINED" : break;
case "SLONG" :
data.position = 0;
_property = 0;
for(i=0;i<propertyNum;i++){
_property += data.readInt();
}break;
case "SRATIONAL" : break;
}
}
return _property;
}
public function get useBytes():uint{
var n:int = ExifTag.TYPE_USE_BYTE[propertyType] * propertyNum;
return n;
}
public function toString():String{
var str:String = "";
str += tag + " :: ";
str += property;
/*
var str2:String = "";
str2 += "tag :: " + tag + "(" + tag.toString(16).toLocaleUpperCase() + ")";
str2 += "\t\t" + "type :: " + ExifTag.TYPE_NAME[ propertyType ] + "(" + propertyType + ")";
str2 += "\t\t\t" + "num :: " + propertyNum;
str2 += "\t\t\t" + "offset :: " + propertyOffset;
str2 += "\t" + "bytes :: " + data.length;
trace(str2);
//*/
return str;
}
}
class MyText extends TextField{
public function MyText( parent:DisplayObjectContainer, width:int, height:int, x:int,y:int){
parent.addChild(this);
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.border = this.background = true;
this.borderColor = 0;
this.backgroundColor = 0xEEEEEE;
}
}