exif-rotate-js
Advanced tools
Comparing version 0.0.9 to 0.0.10
@@ -6,8 +6,6 @@ 'use strict'; | ||
}); | ||
exports.appendNewImages = exports.rotateFromOrientation = exports.canvasResizeAndDrawImage = exports.getOrientation = exports.setImage = undefined; | ||
exports.appendNewImage = exports.rotateFromOrientation = exports.canvasResizeAndDrawImage = exports.getOrientation = exports.setImage = undefined; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _size = require('./configs/size'); | ||
var _exifJs = require('exif-js'); | ||
@@ -17,2 +15,4 @@ | ||
var _configs = require('./configs'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -33,3 +33,3 @@ | ||
*/ | ||
value: function setImage(result_reader) { | ||
value: function setImage(result_reader, options) { | ||
var img = new Image(); | ||
@@ -50,7 +50,7 @@ img.onload = function () { | ||
canvasResizeAndDrawImage(img, canvas, ctx); | ||
canvasResizeAndDrawImage(img, canvas, ctx, options); | ||
rotateFromOrientation(orientation, img, ctx, canvas); | ||
appendNewImage(canvas); | ||
appendNewImage(canvas, options); | ||
}; | ||
@@ -68,17 +68,19 @@ img.src = result_reader; | ||
key: 'canvasResizeAndDrawImage', | ||
value: function canvasResizeAndDrawImage(img, canvas, ctx) { | ||
value: function canvasResizeAndDrawImage(img, canvas, ctx, options) { | ||
var size = options.max_size ? options.max_size : _configs.max_size; | ||
if (img.re_width > img.re_height) { | ||
var resize = img.re_height * (_size.max_size / img.re_width); | ||
canvas.width = _size.max_size; | ||
var resize = img.re_height * (size / img.re_width); | ||
canvas.width = size; | ||
canvas.height = resize; | ||
ctx.drawImage(img, 0, 0, _size.max_size, resize); | ||
ctx.drawImage(img, 0, 0, size, resize); | ||
} else if (img.re_height > img.re_width) { | ||
var _resize = img.re_width * (_size.max_size / img.re_height); | ||
var _resize = img.re_width * (size / img.re_height); | ||
canvas.width = _resize; | ||
canvas.height = _size.max_size; | ||
ctx.drawImage(img, 0, 0, _resize, _size.max_size); | ||
canvas.height = size; | ||
ctx.drawImage(img, 0, 0, _resize, size); | ||
} else { | ||
canvas.width = _size.max_size; | ||
canvas.height = _size.max_size; | ||
ctx.drawImage(img, 0, 0, _size.max_size, _size.max_size); | ||
canvas.width = size; | ||
canvas.height = size; | ||
ctx.drawImage(img, 0, 0, size, size); | ||
} | ||
@@ -108,7 +110,8 @@ } | ||
key: 'appendNewImage', | ||
value: function appendNewImage(canvas) { | ||
value: function appendNewImage(canvas, options) { | ||
var base_64 = canvas.toDataURL('image/jpeg'); | ||
var new_img = new Image(); | ||
new_img.setAttribute('src', base_64); | ||
var container = document.getElementById('container'); | ||
var id = options.container_id ? options.container_id : _configs.default_container_id; | ||
var container = document.getElementById(id); | ||
return container.appendChild(new_img); | ||
@@ -152,7 +155,9 @@ } | ||
case 6: | ||
// 90° rotate right | ||
ctx.rotate(0.5 * Math.PI); | ||
ctx.translate(0, -canvas.height); | ||
var img_ratio = img.re_height / img.re_width - 1; | ||
ctx.drawImage(img, 0, canvas.width * img_ratio, canvas.height, canvas.width); | ||
{ | ||
// 90° rotate right | ||
ctx.rotate(0.5 * Math.PI); | ||
ctx.translate(0, -canvas.height); | ||
var img_ratio = img.re_height / img.re_width - 1; | ||
ctx.drawImage(img, 0, canvas.width * img_ratio, canvas.height, canvas.width); | ||
} | ||
break; | ||
@@ -171,2 +176,4 @@ case 7: | ||
break; | ||
default: | ||
break; | ||
} | ||
@@ -184,3 +191,3 @@ } | ||
var rotateFromOrientation = Helper.rotateFromOrientation; | ||
var appendNewImages = Helper.appendNewImages; | ||
var appendNewImage = Helper.appendNewImage; | ||
exports.setImage = setImage; | ||
@@ -190,2 +197,2 @@ exports.getOrientation = getOrientation; | ||
exports.rotateFromOrientation = rotateFromOrientation; | ||
exports.appendNewImages = appendNewImages; | ||
exports.appendNewImage = appendNewImage; |
1964
lib/sample.js
@@ -49,9 +49,11 @@ /******/ (function(modules) { // webpackBootstrap | ||
var _rotate = __webpack_require__(4); | ||
var _exifRotate = __webpack_require__(4); | ||
var _rotate2 = _interopRequireDefault(_rotate); | ||
var _exifRotate2 = _interopRequireDefault(_exifRotate); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
_rotate2.default.changeFile('file_image'); | ||
_exifRotate2.default.onChangeFile({ | ||
file_id: 'file_image' | ||
}); | ||
@@ -61,1081 +63,1149 @@ /***/ }, | ||
/* 2 */, | ||
/* 3 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
/* 3 */, | ||
/* 4 */ | ||
/***/ function(module, exports) { | ||
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function() { | ||
"use strict"; | ||
var debug = false; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; | ||
var root = this; | ||
/******/(function (modules) { | ||
// webpackBootstrap | ||
/******/ // The module cache | ||
/******/var installedModules = {}; | ||
var EXIF = function(obj) { | ||
if (obj instanceof EXIF) return obj; | ||
if (!(this instanceof EXIF)) return new EXIF(obj); | ||
this.EXIFwrapped = obj; | ||
}; | ||
/******/ // The require function | ||
/******/function __webpack_require__(moduleId) { | ||
if (true) { | ||
if (typeof module !== 'undefined' && module.exports) { | ||
exports = module.exports = EXIF; | ||
} | ||
exports.EXIF = EXIF; | ||
} else { | ||
root.EXIF = EXIF; | ||
} | ||
/******/ // Check if module is in cache | ||
/******/if (installedModules[moduleId]) | ||
/******/return installedModules[moduleId].exports; | ||
var ExifTags = EXIF.Tags = { | ||
/******/ // Create a new module (and put it into the cache) | ||
/******/var module = installedModules[moduleId] = { | ||
/******/exports: {}, | ||
/******/id: moduleId, | ||
/******/loaded: false | ||
/******/ }; | ||
// version tags | ||
0x9000 : "ExifVersion", // EXIF version | ||
0xA000 : "FlashpixVersion", // Flashpix format version | ||
/******/ // Execute the module function | ||
/******/modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||
// colorspace tags | ||
0xA001 : "ColorSpace", // Color space information tag | ||
/******/ // Flag the module as loaded | ||
/******/module.loaded = true; | ||
// image configuration | ||
0xA002 : "PixelXDimension", // Valid width of meaningful image | ||
0xA003 : "PixelYDimension", // Valid height of meaningful image | ||
0x9101 : "ComponentsConfiguration", // Information about channels | ||
0x9102 : "CompressedBitsPerPixel", // Compressed bits per pixel | ||
/******/ // Return the exports of the module | ||
/******/return module.exports; | ||
/******/ | ||
} | ||
// user information | ||
0x927C : "MakerNote", // Any desired information written by the manufacturer | ||
0x9286 : "UserComment", // Comments by user | ||
/******/ // expose the modules object (__webpack_modules__) | ||
/******/__webpack_require__.m = modules; | ||
// related file | ||
0xA004 : "RelatedSoundFile", // Name of related sound file | ||
/******/ // expose the module cache | ||
/******/__webpack_require__.c = installedModules; | ||
// date and time | ||
0x9003 : "DateTimeOriginal", // Date and time when the original image was generated | ||
0x9004 : "DateTimeDigitized", // Date and time when the image was stored digitally | ||
0x9290 : "SubsecTime", // Fractions of seconds for DateTime | ||
0x9291 : "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal | ||
0x9292 : "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized | ||
/******/ // __webpack_public_path__ | ||
/******/__webpack_require__.p = ""; | ||
// picture-taking conditions | ||
0x829A : "ExposureTime", // Exposure time (in seconds) | ||
0x829D : "FNumber", // F number | ||
0x8822 : "ExposureProgram", // Exposure program | ||
0x8824 : "SpectralSensitivity", // Spectral sensitivity | ||
0x8827 : "ISOSpeedRatings", // ISO speed rating | ||
0x8828 : "OECF", // Optoelectric conversion factor | ||
0x9201 : "ShutterSpeedValue", // Shutter speed | ||
0x9202 : "ApertureValue", // Lens aperture | ||
0x9203 : "BrightnessValue", // Value of brightness | ||
0x9204 : "ExposureBias", // Exposure bias | ||
0x9205 : "MaxApertureValue", // Smallest F number of lens | ||
0x9206 : "SubjectDistance", // Distance to subject in meters | ||
0x9207 : "MeteringMode", // Metering mode | ||
0x9208 : "LightSource", // Kind of light source | ||
0x9209 : "Flash", // Flash status | ||
0x9214 : "SubjectArea", // Location and area of main subject | ||
0x920A : "FocalLength", // Focal length of the lens in mm | ||
0xA20B : "FlashEnergy", // Strobe energy in BCPS | ||
0xA20C : "SpatialFrequencyResponse", // | ||
0xA20E : "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit | ||
0xA20F : "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit | ||
0xA210 : "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution | ||
0xA214 : "SubjectLocation", // Location of subject in image | ||
0xA215 : "ExposureIndex", // Exposure index selected on camera | ||
0xA217 : "SensingMethod", // Image sensor type | ||
0xA300 : "FileSource", // Image source (3 == DSC) | ||
0xA301 : "SceneType", // Scene type (1 == directly photographed) | ||
0xA302 : "CFAPattern", // Color filter array geometric pattern | ||
0xA401 : "CustomRendered", // Special processing | ||
0xA402 : "ExposureMode", // Exposure mode | ||
0xA403 : "WhiteBalance", // 1 = auto white balance, 2 = manual | ||
0xA404 : "DigitalZoomRation", // Digital zoom ratio | ||
0xA405 : "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm) | ||
0xA406 : "SceneCaptureType", // Type of scene | ||
0xA407 : "GainControl", // Degree of overall image gain adjustment | ||
0xA408 : "Contrast", // Direction of contrast processing applied by camera | ||
0xA409 : "Saturation", // Direction of saturation processing applied by camera | ||
0xA40A : "Sharpness", // Direction of sharpness processing applied by camera | ||
0xA40B : "DeviceSettingDescription", // | ||
0xA40C : "SubjectDistanceRange", // Distance to subject | ||
/******/ // Load entry module and return exports | ||
/******/return __webpack_require__(0); | ||
/******/ | ||
})( | ||
/************************************************************************/ | ||
/******/[ | ||
/* 0 */ | ||
/***/function (module, exports, __webpack_require__) { | ||
// other tags | ||
0xA005 : "InteroperabilityIFDPointer", | ||
0xA420 : "ImageUniqueID" // Identifier assigned uniquely to each image | ||
}; | ||
'use strict'; | ||
var TiffTags = EXIF.TiffTags = { | ||
0x0100 : "ImageWidth", | ||
0x0101 : "ImageHeight", | ||
0x8769 : "ExifIFDPointer", | ||
0x8825 : "GPSInfoIFDPointer", | ||
0xA005 : "InteroperabilityIFDPointer", | ||
0x0102 : "BitsPerSample", | ||
0x0103 : "Compression", | ||
0x0106 : "PhotometricInterpretation", | ||
0x0112 : "Orientation", | ||
0x0115 : "SamplesPerPixel", | ||
0x011C : "PlanarConfiguration", | ||
0x0212 : "YCbCrSubSampling", | ||
0x0213 : "YCbCrPositioning", | ||
0x011A : "XResolution", | ||
0x011B : "YResolution", | ||
0x0128 : "ResolutionUnit", | ||
0x0111 : "StripOffsets", | ||
0x0116 : "RowsPerStrip", | ||
0x0117 : "StripByteCounts", | ||
0x0201 : "JPEGInterchangeFormat", | ||
0x0202 : "JPEGInterchangeFormatLength", | ||
0x012D : "TransferFunction", | ||
0x013E : "WhitePoint", | ||
0x013F : "PrimaryChromaticities", | ||
0x0211 : "YCbCrCoefficients", | ||
0x0214 : "ReferenceBlackWhite", | ||
0x0132 : "DateTime", | ||
0x010E : "ImageDescription", | ||
0x010F : "Make", | ||
0x0110 : "Model", | ||
0x0131 : "Software", | ||
0x013B : "Artist", | ||
0x8298 : "Copyright" | ||
}; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var GPSTags = EXIF.GPSTags = { | ||
0x0000 : "GPSVersionID", | ||
0x0001 : "GPSLatitudeRef", | ||
0x0002 : "GPSLatitude", | ||
0x0003 : "GPSLongitudeRef", | ||
0x0004 : "GPSLongitude", | ||
0x0005 : "GPSAltitudeRef", | ||
0x0006 : "GPSAltitude", | ||
0x0007 : "GPSTimeStamp", | ||
0x0008 : "GPSSatellites", | ||
0x0009 : "GPSStatus", | ||
0x000A : "GPSMeasureMode", | ||
0x000B : "GPSDOP", | ||
0x000C : "GPSSpeedRef", | ||
0x000D : "GPSSpeed", | ||
0x000E : "GPSTrackRef", | ||
0x000F : "GPSTrack", | ||
0x0010 : "GPSImgDirectionRef", | ||
0x0011 : "GPSImgDirection", | ||
0x0012 : "GPSMapDatum", | ||
0x0013 : "GPSDestLatitudeRef", | ||
0x0014 : "GPSDestLatitude", | ||
0x0015 : "GPSDestLongitudeRef", | ||
0x0016 : "GPSDestLongitude", | ||
0x0017 : "GPSDestBearingRef", | ||
0x0018 : "GPSDestBearing", | ||
0x0019 : "GPSDestDistanceRef", | ||
0x001A : "GPSDestDistance", | ||
0x001B : "GPSProcessingMethod", | ||
0x001C : "GPSAreaInformation", | ||
0x001D : "GPSDateStamp", | ||
0x001E : "GPSDifferential" | ||
}; | ||
var _createClass = function () { | ||
function defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
}return function (Constructor, protoProps, staticProps) { | ||
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; | ||
}; | ||
}(); | ||
var StringValues = EXIF.StringValues = { | ||
ExposureProgram : { | ||
0 : "Not defined", | ||
1 : "Manual", | ||
2 : "Normal program", | ||
3 : "Aperture priority", | ||
4 : "Shutter priority", | ||
5 : "Creative program", | ||
6 : "Action program", | ||
7 : "Portrait mode", | ||
8 : "Landscape mode" | ||
}, | ||
MeteringMode : { | ||
0 : "Unknown", | ||
1 : "Average", | ||
2 : "CenterWeightedAverage", | ||
3 : "Spot", | ||
4 : "MultiSpot", | ||
5 : "Pattern", | ||
6 : "Partial", | ||
255 : "Other" | ||
}, | ||
LightSource : { | ||
0 : "Unknown", | ||
1 : "Daylight", | ||
2 : "Fluorescent", | ||
3 : "Tungsten (incandescent light)", | ||
4 : "Flash", | ||
9 : "Fine weather", | ||
10 : "Cloudy weather", | ||
11 : "Shade", | ||
12 : "Daylight fluorescent (D 5700 - 7100K)", | ||
13 : "Day white fluorescent (N 4600 - 5400K)", | ||
14 : "Cool white fluorescent (W 3900 - 4500K)", | ||
15 : "White fluorescent (WW 3200 - 3700K)", | ||
17 : "Standard light A", | ||
18 : "Standard light B", | ||
19 : "Standard light C", | ||
20 : "D55", | ||
21 : "D65", | ||
22 : "D75", | ||
23 : "D50", | ||
24 : "ISO studio tungsten", | ||
255 : "Other" | ||
}, | ||
Flash : { | ||
0x0000 : "Flash did not fire", | ||
0x0001 : "Flash fired", | ||
0x0005 : "Strobe return light not detected", | ||
0x0007 : "Strobe return light detected", | ||
0x0009 : "Flash fired, compulsory flash mode", | ||
0x000D : "Flash fired, compulsory flash mode, return light not detected", | ||
0x000F : "Flash fired, compulsory flash mode, return light detected", | ||
0x0010 : "Flash did not fire, compulsory flash mode", | ||
0x0018 : "Flash did not fire, auto mode", | ||
0x0019 : "Flash fired, auto mode", | ||
0x001D : "Flash fired, auto mode, return light not detected", | ||
0x001F : "Flash fired, auto mode, return light detected", | ||
0x0020 : "No flash function", | ||
0x0041 : "Flash fired, red-eye reduction mode", | ||
0x0045 : "Flash fired, red-eye reduction mode, return light not detected", | ||
0x0047 : "Flash fired, red-eye reduction mode, return light detected", | ||
0x0049 : "Flash fired, compulsory flash mode, red-eye reduction mode", | ||
0x004D : "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected", | ||
0x004F : "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected", | ||
0x0059 : "Flash fired, auto mode, red-eye reduction mode", | ||
0x005D : "Flash fired, auto mode, return light not detected, red-eye reduction mode", | ||
0x005F : "Flash fired, auto mode, return light detected, red-eye reduction mode" | ||
}, | ||
SensingMethod : { | ||
1 : "Not defined", | ||
2 : "One-chip color area sensor", | ||
3 : "Two-chip color area sensor", | ||
4 : "Three-chip color area sensor", | ||
5 : "Color sequential area sensor", | ||
7 : "Trilinear sensor", | ||
8 : "Color sequential linear sensor" | ||
}, | ||
SceneCaptureType : { | ||
0 : "Standard", | ||
1 : "Landscape", | ||
2 : "Portrait", | ||
3 : "Night scene" | ||
}, | ||
SceneType : { | ||
1 : "Directly photographed" | ||
}, | ||
CustomRendered : { | ||
0 : "Normal process", | ||
1 : "Custom process" | ||
}, | ||
WhiteBalance : { | ||
0 : "Auto white balance", | ||
1 : "Manual white balance" | ||
}, | ||
GainControl : { | ||
0 : "None", | ||
1 : "Low gain up", | ||
2 : "High gain up", | ||
3 : "Low gain down", | ||
4 : "High gain down" | ||
}, | ||
Contrast : { | ||
0 : "Normal", | ||
1 : "Soft", | ||
2 : "Hard" | ||
}, | ||
Saturation : { | ||
0 : "Normal", | ||
1 : "Low saturation", | ||
2 : "High saturation" | ||
}, | ||
Sharpness : { | ||
0 : "Normal", | ||
1 : "Soft", | ||
2 : "Hard" | ||
}, | ||
SubjectDistanceRange : { | ||
0 : "Unknown", | ||
1 : "Macro", | ||
2 : "Close view", | ||
3 : "Distant view" | ||
}, | ||
FileSource : { | ||
3 : "DSC" | ||
}, | ||
var _helper = __webpack_require__(1); | ||
Components : { | ||
0 : "", | ||
1 : "Y", | ||
2 : "Cb", | ||
3 : "Cr", | ||
4 : "R", | ||
5 : "G", | ||
6 : "B" | ||
} | ||
}; | ||
var _configs = __webpack_require__(3); | ||
function addEvent(element, event, handler) { | ||
if (element.addEventListener) { | ||
element.addEventListener(event, handler, false); | ||
} else if (element.attachEvent) { | ||
element.attachEvent("on" + event, handler); | ||
} | ||
} | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
function imageHasData(img) { | ||
return !!(img.exifdata); | ||
} | ||
var ExifRotate = function () { | ||
function ExifRotate() { | ||
_classCallCheck(this, ExifRotate); | ||
} | ||
_createClass(ExifRotate, null, [{ | ||
key: 'onChangeFile', | ||
function base64ToArrayBuffer(base64, contentType) { | ||
contentType = contentType || base64.match(/^data\:([^\;]+)\;base64,/mi)[1] || ''; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg' | ||
base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, ''); | ||
var binary = atob(base64); | ||
var len = binary.length; | ||
var buffer = new ArrayBuffer(len); | ||
var view = new Uint8Array(buffer); | ||
for (var i = 0; i < len; i++) { | ||
view[i] = binary.charCodeAt(i); | ||
} | ||
return buffer; | ||
} | ||
/** | ||
* @param options {object} | ||
* elem_id: string | ||
* max_size: number | ||
* container_id: string | ||
*/ | ||
value: function onChangeFile() { | ||
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
function objectURLToBlob(url, callback) { | ||
var http = new XMLHttpRequest(); | ||
http.open("GET", url, true); | ||
http.responseType = "blob"; | ||
http.onload = function(e) { | ||
if (this.status == 200 || this.status === 0) { | ||
callback(this.response); | ||
} | ||
}; | ||
http.send(); | ||
} | ||
var id = options.file_id ? options.file_id : _configs.file_id; | ||
var elem = document.getElementById(id); | ||
function getImageData(img, callback) { | ||
function handleBinaryFile(binFile) { | ||
var data = findEXIFinJPEG(binFile); | ||
var iptcdata = findIPTCinJPEG(binFile); | ||
img.exifdata = data || {}; | ||
img.iptcdata = iptcdata || {}; | ||
if (callback) { | ||
callback.call(img); | ||
} | ||
} | ||
elem.onchange = function (e) { | ||
Object.keys(e.target.files).forEach(function (index) { | ||
var reader = new FileReader(); | ||
reader.onload = function (e) { | ||
(0, _helper.setImage)(e.target.result, options); | ||
}; | ||
reader.readAsDataURL(e.target.files[index]); | ||
}); | ||
}; | ||
} | ||
}]); | ||
if (img.src) { | ||
if (/^data\:/i.test(img.src)) { // Data URI | ||
var arrayBuffer = base64ToArrayBuffer(img.src); | ||
handleBinaryFile(arrayBuffer); | ||
return ExifRotate; | ||
}(); | ||
} else if (/^blob\:/i.test(img.src)) { // Object URL | ||
var fileReader = new FileReader(); | ||
fileReader.onload = function(e) { | ||
handleBinaryFile(e.target.result); | ||
}; | ||
objectURLToBlob(img.src, function (blob) { | ||
fileReader.readAsArrayBuffer(blob); | ||
}); | ||
} else { | ||
var http = new XMLHttpRequest(); | ||
http.onload = function() { | ||
if (this.status == 200 || this.status === 0) { | ||
handleBinaryFile(http.response); | ||
} else { | ||
throw "Could not load image"; | ||
} | ||
http = null; | ||
}; | ||
http.open("GET", img.src, true); | ||
http.responseType = "arraybuffer"; | ||
http.send(null); | ||
} | ||
} else if (window.FileReader && (img instanceof window.Blob || img instanceof window.File)) { | ||
var fileReader = new FileReader(); | ||
fileReader.onload = function(e) { | ||
if (debug) console.log("Got file of length " + e.target.result.byteLength); | ||
handleBinaryFile(e.target.result); | ||
}; | ||
exports.default = ExifRotate; | ||
fileReader.readAsArrayBuffer(img); | ||
} | ||
} | ||
ExifRotate.onChangeFile({ | ||
file_id: 'file_image' | ||
}); | ||
function findEXIFinJPEG(file) { | ||
var dataView = new DataView(file); | ||
/***/ | ||
}, | ||
/* 1 */ | ||
/***/function (module, exports, __webpack_require__) { | ||
if (debug) console.log("Got file of length " + file.byteLength); | ||
if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { | ||
if (debug) console.log("Not a valid JPEG"); | ||
return false; // not a valid jpeg | ||
} | ||
'use strict'; | ||
var offset = 2, | ||
length = file.byteLength, | ||
marker; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.appendNewImage = exports.rotateFromOrientation = exports.canvasResizeAndDrawImage = exports.getOrientation = exports.setImage = undefined; | ||
while (offset < length) { | ||
if (dataView.getUint8(offset) != 0xFF) { | ||
if (debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(offset)); | ||
return false; // not a valid marker, something is wrong | ||
} | ||
var _createClass = function () { | ||
function defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
}return function (Constructor, protoProps, staticProps) { | ||
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; | ||
}; | ||
}(); | ||
marker = dataView.getUint8(offset + 1); | ||
if (debug) console.log(marker); | ||
var _exifJs = __webpack_require__(2); | ||
// we could implement handling for other markers here, | ||
// but we're only looking for 0xFFE1 for EXIF data | ||
var _exifJs2 = _interopRequireDefault(_exifJs); | ||
if (marker == 225) { | ||
if (debug) console.log("Found 0xFFE1 marker"); | ||
var _configs = __webpack_require__(3); | ||
return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2); | ||
function _interopRequireDefault(obj) { | ||
return obj && obj.__esModule ? obj : { default: obj }; | ||
} | ||
// offset += 2 + file.getShortAt(offset+2, true); | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
} else { | ||
offset += 2 + dataView.getUint16(offset+2); | ||
} | ||
var Helper = function () { | ||
function Helper() { | ||
_classCallCheck(this, Helper); | ||
} | ||
} | ||
_createClass(Helper, null, [{ | ||
key: 'setImage', | ||
} | ||
/** | ||
* @param result_reader {string} base64 の string | ||
*/ | ||
value: function setImage(result_reader, options) { | ||
var img = new Image(); | ||
img.onload = function () { | ||
var canvas = document.createElement('canvas'); | ||
var ctx = canvas.getContext('2d'); | ||
img.re_width = img.width; | ||
img.re_height = img.height; | ||
function findIPTCinJPEG(file) { | ||
var dataView = new DataView(file); | ||
var orientation = getOrientation(img); | ||
if (debug) console.log("Got file of length " + file.byteLength); | ||
if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { | ||
if (debug) console.log("Not a valid JPEG"); | ||
return false; // not a valid jpeg | ||
} | ||
if (orientation === 6) { | ||
// 縦画像だった場合スマートフォンでは幅・高さは横画像と認識されるため、 width height を手動で入れ替える必要あり | ||
img.re_height = img.width; | ||
img.re_width = img.height; | ||
} | ||
var offset = 2, | ||
length = file.byteLength; | ||
canvasResizeAndDrawImage(img, canvas, ctx, options); | ||
rotateFromOrientation(orientation, img, ctx, canvas); | ||
var isFieldSegmentStart = function(dataView, offset){ | ||
return ( | ||
dataView.getUint8(offset) === 0x38 && | ||
dataView.getUint8(offset+1) === 0x42 && | ||
dataView.getUint8(offset+2) === 0x49 && | ||
dataView.getUint8(offset+3) === 0x4D && | ||
dataView.getUint8(offset+4) === 0x04 && | ||
dataView.getUint8(offset+5) === 0x04 | ||
); | ||
}; | ||
appendNewImage(canvas, options); | ||
}; | ||
img.src = result_reader; | ||
} | ||
while (offset < length) { | ||
/** | ||
* @param img {elem} | ||
* @param canvas {elem} | ||
* @param ctx {canvas obj} | ||
*/ | ||
if ( isFieldSegmentStart(dataView, offset )){ | ||
}, { | ||
key: 'canvasResizeAndDrawImage', | ||
value: function canvasResizeAndDrawImage(img, canvas, ctx, options) { | ||
var size = options.max_size ? options.max_size : _configs.max_size; | ||
// Get the length of the name header (which is padded to an even number of bytes) | ||
var nameHeaderLength = dataView.getUint8(offset+7); | ||
if(nameHeaderLength % 2 !== 0) nameHeaderLength += 1; | ||
// Check for pre photoshop 6 format | ||
if(nameHeaderLength === 0) { | ||
// Always 4 | ||
nameHeaderLength = 4; | ||
} | ||
if (img.re_width > img.re_height) { | ||
var resize = img.re_height * (size / img.re_width); | ||
canvas.width = size; | ||
canvas.height = resize; | ||
ctx.drawImage(img, 0, 0, size, resize); | ||
} else if (img.re_height > img.re_width) { | ||
var _resize = img.re_width * (size / img.re_height); | ||
canvas.width = _resize; | ||
canvas.height = size; | ||
ctx.drawImage(img, 0, 0, _resize, size); | ||
} else { | ||
canvas.width = size; | ||
canvas.height = size; | ||
ctx.drawImage(img, 0, 0, size, size); | ||
} | ||
} | ||
var startOffset = offset + 8 + nameHeaderLength; | ||
var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength); | ||
/** | ||
* @param img {elem} | ||
*/ | ||
return readIPTCData(file, startOffset, sectionLength); | ||
}, { | ||
key: 'getOrientation', | ||
value: function getOrientation(img) { | ||
var orientation = void 0; | ||
_exifJs2.default.getData(img, function () { | ||
orientation = _exifJs2.default.getTag(img, 'Orientation'); | ||
}); | ||
return orientation; | ||
} | ||
break; | ||
/** | ||
* #container に append | ||
* @param canvas {elem} | ||
*/ | ||
} | ||
}, { | ||
key: 'appendNewImage', | ||
value: function appendNewImage(canvas, options) { | ||
var base_64 = canvas.toDataURL('image/jpeg'); | ||
var new_img = new Image(); | ||
new_img.setAttribute('src', base_64); | ||
var id = options.container_id ? options.container_id : _configs.default_container_id; | ||
var container = document.getElementById(id); | ||
return container.appendChild(new_img); | ||
} | ||
/** | ||
* for mobile | ||
* orientation があった場合に正しい角度で見せるように canvas を使って回転させる | ||
* @param orientation {number} | ||
* @param img {elem} | ||
* @param ctx {canvas obj} | ||
* @param canvas {elem} | ||
*/ | ||
// Not the marker, continue searching | ||
offset++; | ||
}, { | ||
key: 'rotateFromOrientation', | ||
value: function rotateFromOrientation(orientation, img, ctx, canvas) { | ||
switch (orientation) { | ||
case 2: | ||
// horizontal flip | ||
ctx.translate(canvas.width, 0); | ||
ctx.scale(-1, 1); | ||
break; | ||
case 3: | ||
// 180° rotate left | ||
ctx.translate(canvas.width, canvas.height); | ||
ctx.rotate(Math.PI); | ||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height); | ||
break; | ||
case 4: | ||
// vertical flip | ||
ctx.translate(0, canvas.height); | ||
ctx.scale(1, -1); | ||
break; | ||
case 5: | ||
// vertical flip + 90 rotate right | ||
ctx.rotate(0.5 * Math.PI); | ||
ctx.scale(1, -1); | ||
break; | ||
case 6: | ||
{ | ||
// 90° rotate right | ||
ctx.rotate(0.5 * Math.PI); | ||
ctx.translate(0, -canvas.height); | ||
var img_ratio = img.re_height / img.re_width - 1; | ||
ctx.drawImage(img, 0, canvas.width * img_ratio, canvas.height, canvas.width); | ||
} | ||
break; | ||
case 7: | ||
// horizontal flip + 90 rotate right | ||
ctx.rotate(0.5 * Math.PI); | ||
ctx.translate(canvas.width, -canvas.height); | ||
ctx.scale(-1, 1); | ||
break; | ||
case 8: | ||
// 90° rotate left | ||
ctx.rotate(-0.5 * Math.PI); | ||
ctx.translate(-canvas.width, 0); | ||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
}]); | ||
} | ||
return Helper; | ||
}(); | ||
} | ||
var IptcFieldMap = { | ||
0x78 : 'caption', | ||
0x6E : 'credit', | ||
0x19 : 'keywords', | ||
0x37 : 'dateCreated', | ||
0x50 : 'byline', | ||
0x55 : 'bylineTitle', | ||
0x7A : 'captionWriter', | ||
0x69 : 'headline', | ||
0x74 : 'copyright', | ||
0x0F : 'category' | ||
}; | ||
function readIPTCData(file, startOffset, sectionLength){ | ||
var dataView = new DataView(file); | ||
var data = {}; | ||
var fieldValue, fieldName, dataSize, segmentType, segmentSize; | ||
var segmentStartPos = startOffset; | ||
while(segmentStartPos < startOffset+sectionLength) { | ||
if(dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos+1) === 0x02){ | ||
segmentType = dataView.getUint8(segmentStartPos+2); | ||
if(segmentType in IptcFieldMap) { | ||
dataSize = dataView.getInt16(segmentStartPos+3); | ||
segmentSize = dataSize + 5; | ||
fieldName = IptcFieldMap[segmentType]; | ||
fieldValue = getStringFromDB(dataView, segmentStartPos+5, dataSize); | ||
// Check if we already stored a value with this name | ||
if(data.hasOwnProperty(fieldName)) { | ||
// Value already stored with this name, create multivalue field | ||
if(data[fieldName] instanceof Array) { | ||
data[fieldName].push(fieldValue); | ||
} | ||
else { | ||
data[fieldName] = [data[fieldName], fieldValue]; | ||
} | ||
} | ||
else { | ||
data[fieldName] = fieldValue; | ||
} | ||
} | ||
exports.default = Helper; | ||
var setImage = Helper.setImage; | ||
var getOrientation = Helper.getOrientation; | ||
var canvasResizeAndDrawImage = Helper.canvasResizeAndDrawImage; | ||
var rotateFromOrientation = Helper.rotateFromOrientation; | ||
var appendNewImage = Helper.appendNewImage; | ||
exports.setImage = setImage; | ||
exports.getOrientation = getOrientation; | ||
exports.canvasResizeAndDrawImage = canvasResizeAndDrawImage; | ||
exports.rotateFromOrientation = rotateFromOrientation; | ||
exports.appendNewImage = appendNewImage; | ||
} | ||
segmentStartPos++; | ||
} | ||
return data; | ||
} | ||
/***/ | ||
}, | ||
/* 2 */ | ||
/***/function (module, exports, __webpack_require__) { | ||
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function () { | ||
var debug = false; | ||
function readTags(file, tiffStart, dirStart, strings, bigEnd) { | ||
var entries = file.getUint16(dirStart, !bigEnd), | ||
tags = {}, | ||
entryOffset, tag, | ||
i; | ||
var root = this; | ||
for (i=0;i<entries;i++) { | ||
entryOffset = dirStart + i*12 + 2; | ||
tag = strings[file.getUint16(entryOffset, !bigEnd)]; | ||
if (!tag && debug) console.log("Unknown tag: " + file.getUint16(entryOffset, !bigEnd)); | ||
tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd); | ||
} | ||
return tags; | ||
} | ||
var EXIF = function EXIF(obj) { | ||
if (obj instanceof EXIF) return obj; | ||
if (!(this instanceof EXIF)) return new EXIF(obj); | ||
this.EXIFwrapped = obj; | ||
}; | ||
if (true) { | ||
if (typeof module !== 'undefined' && module.exports) { | ||
exports = module.exports = EXIF; | ||
} | ||
exports.EXIF = EXIF; | ||
} else { | ||
root.EXIF = EXIF; | ||
} | ||
function readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd) { | ||
var type = file.getUint16(entryOffset+2, !bigEnd), | ||
numValues = file.getUint32(entryOffset+4, !bigEnd), | ||
valueOffset = file.getUint32(entryOffset+8, !bigEnd) + tiffStart, | ||
offset, | ||
vals, val, n, | ||
numerator, denominator; | ||
var ExifTags = EXIF.Tags = { | ||
switch (type) { | ||
case 1: // byte, 8-bit unsigned int | ||
case 7: // undefined, 8-bit byte, value depending on field | ||
if (numValues == 1) { | ||
return file.getUint8(entryOffset + 8, !bigEnd); | ||
} else { | ||
offset = numValues > 4 ? valueOffset : (entryOffset + 8); | ||
vals = []; | ||
for (n=0;n<numValues;n++) { | ||
vals[n] = file.getUint8(offset + n); | ||
} | ||
return vals; | ||
} | ||
// version tags | ||
0x9000: "ExifVersion", // EXIF version | ||
0xA000: "FlashpixVersion", // Flashpix format version | ||
case 2: // ascii, 8-bit byte | ||
offset = numValues > 4 ? valueOffset : (entryOffset + 8); | ||
return getStringFromDB(file, offset, numValues-1); | ||
// colorspace tags | ||
0xA001: "ColorSpace", // Color space information tag | ||
case 3: // short, 16 bit int | ||
if (numValues == 1) { | ||
return file.getUint16(entryOffset + 8, !bigEnd); | ||
} else { | ||
offset = numValues > 2 ? valueOffset : (entryOffset + 8); | ||
vals = []; | ||
for (n=0;n<numValues;n++) { | ||
vals[n] = file.getUint16(offset + 2*n, !bigEnd); | ||
} | ||
return vals; | ||
} | ||
// image configuration | ||
0xA002: "PixelXDimension", // Valid width of meaningful image | ||
0xA003: "PixelYDimension", // Valid height of meaningful image | ||
0x9101: "ComponentsConfiguration", // Information about channels | ||
0x9102: "CompressedBitsPerPixel", // Compressed bits per pixel | ||
case 4: // long, 32 bit int | ||
if (numValues == 1) { | ||
return file.getUint32(entryOffset + 8, !bigEnd); | ||
} else { | ||
vals = []; | ||
for (n=0;n<numValues;n++) { | ||
vals[n] = file.getUint32(valueOffset + 4*n, !bigEnd); | ||
} | ||
return vals; | ||
} | ||
// user information | ||
0x927C: "MakerNote", // Any desired information written by the manufacturer | ||
0x9286: "UserComment", // Comments by user | ||
case 5: // rational = two long values, first is numerator, second is denominator | ||
if (numValues == 1) { | ||
numerator = file.getUint32(valueOffset, !bigEnd); | ||
denominator = file.getUint32(valueOffset+4, !bigEnd); | ||
val = new Number(numerator / denominator); | ||
val.numerator = numerator; | ||
val.denominator = denominator; | ||
return val; | ||
} else { | ||
vals = []; | ||
for (n=0;n<numValues;n++) { | ||
numerator = file.getUint32(valueOffset + 8*n, !bigEnd); | ||
denominator = file.getUint32(valueOffset+4 + 8*n, !bigEnd); | ||
vals[n] = new Number(numerator / denominator); | ||
vals[n].numerator = numerator; | ||
vals[n].denominator = denominator; | ||
} | ||
return vals; | ||
} | ||
// related file | ||
0xA004: "RelatedSoundFile", // Name of related sound file | ||
case 9: // slong, 32 bit signed int | ||
if (numValues == 1) { | ||
return file.getInt32(entryOffset + 8, !bigEnd); | ||
} else { | ||
vals = []; | ||
for (n=0;n<numValues;n++) { | ||
vals[n] = file.getInt32(valueOffset + 4*n, !bigEnd); | ||
} | ||
return vals; | ||
} | ||
// date and time | ||
0x9003: "DateTimeOriginal", // Date and time when the original image was generated | ||
0x9004: "DateTimeDigitized", // Date and time when the image was stored digitally | ||
0x9290: "SubsecTime", // Fractions of seconds for DateTime | ||
0x9291: "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal | ||
0x9292: "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized | ||
case 10: // signed rational, two slongs, first is numerator, second is denominator | ||
if (numValues == 1) { | ||
return file.getInt32(valueOffset, !bigEnd) / file.getInt32(valueOffset+4, !bigEnd); | ||
} else { | ||
vals = []; | ||
for (n=0;n<numValues;n++) { | ||
vals[n] = file.getInt32(valueOffset + 8*n, !bigEnd) / file.getInt32(valueOffset+4 + 8*n, !bigEnd); | ||
} | ||
return vals; | ||
} | ||
} | ||
} | ||
// picture-taking conditions | ||
0x829A: "ExposureTime", // Exposure time (in seconds) | ||
0x829D: "FNumber", // F number | ||
0x8822: "ExposureProgram", // Exposure program | ||
0x8824: "SpectralSensitivity", // Spectral sensitivity | ||
0x8827: "ISOSpeedRatings", // ISO speed rating | ||
0x8828: "OECF", // Optoelectric conversion factor | ||
0x9201: "ShutterSpeedValue", // Shutter speed | ||
0x9202: "ApertureValue", // Lens aperture | ||
0x9203: "BrightnessValue", // Value of brightness | ||
0x9204: "ExposureBias", // Exposure bias | ||
0x9205: "MaxApertureValue", // Smallest F number of lens | ||
0x9206: "SubjectDistance", // Distance to subject in meters | ||
0x9207: "MeteringMode", // Metering mode | ||
0x9208: "LightSource", // Kind of light source | ||
0x9209: "Flash", // Flash status | ||
0x9214: "SubjectArea", // Location and area of main subject | ||
0x920A: "FocalLength", // Focal length of the lens in mm | ||
0xA20B: "FlashEnergy", // Strobe energy in BCPS | ||
0xA20C: "SpatialFrequencyResponse", // | ||
0xA20E: "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit | ||
0xA20F: "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit | ||
0xA210: "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution | ||
0xA214: "SubjectLocation", // Location of subject in image | ||
0xA215: "ExposureIndex", // Exposure index selected on camera | ||
0xA217: "SensingMethod", // Image sensor type | ||
0xA300: "FileSource", // Image source (3 == DSC) | ||
0xA301: "SceneType", // Scene type (1 == directly photographed) | ||
0xA302: "CFAPattern", // Color filter array geometric pattern | ||
0xA401: "CustomRendered", // Special processing | ||
0xA402: "ExposureMode", // Exposure mode | ||
0xA403: "WhiteBalance", // 1 = auto white balance, 2 = manual | ||
0xA404: "DigitalZoomRation", // Digital zoom ratio | ||
0xA405: "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm) | ||
0xA406: "SceneCaptureType", // Type of scene | ||
0xA407: "GainControl", // Degree of overall image gain adjustment | ||
0xA408: "Contrast", // Direction of contrast processing applied by camera | ||
0xA409: "Saturation", // Direction of saturation processing applied by camera | ||
0xA40A: "Sharpness", // Direction of sharpness processing applied by camera | ||
0xA40B: "DeviceSettingDescription", // | ||
0xA40C: "SubjectDistanceRange", // Distance to subject | ||
function getStringFromDB(buffer, start, length) { | ||
var outstr = ""; | ||
for (n = start; n < start+length; n++) { | ||
outstr += String.fromCharCode(buffer.getUint8(n)); | ||
} | ||
return outstr; | ||
} | ||
// other tags | ||
0xA005: "InteroperabilityIFDPointer", | ||
0xA420: "ImageUniqueID" // Identifier assigned uniquely to each image | ||
}; | ||
function readEXIFData(file, start) { | ||
if (getStringFromDB(file, start, 4) != "Exif") { | ||
if (debug) console.log("Not valid EXIF data! " + getStringFromDB(file, start, 4)); | ||
return false; | ||
} | ||
var TiffTags = EXIF.TiffTags = { | ||
0x0100: "ImageWidth", | ||
0x0101: "ImageHeight", | ||
0x8769: "ExifIFDPointer", | ||
0x8825: "GPSInfoIFDPointer", | ||
0xA005: "InteroperabilityIFDPointer", | ||
0x0102: "BitsPerSample", | ||
0x0103: "Compression", | ||
0x0106: "PhotometricInterpretation", | ||
0x0112: "Orientation", | ||
0x0115: "SamplesPerPixel", | ||
0x011C: "PlanarConfiguration", | ||
0x0212: "YCbCrSubSampling", | ||
0x0213: "YCbCrPositioning", | ||
0x011A: "XResolution", | ||
0x011B: "YResolution", | ||
0x0128: "ResolutionUnit", | ||
0x0111: "StripOffsets", | ||
0x0116: "RowsPerStrip", | ||
0x0117: "StripByteCounts", | ||
0x0201: "JPEGInterchangeFormat", | ||
0x0202: "JPEGInterchangeFormatLength", | ||
0x012D: "TransferFunction", | ||
0x013E: "WhitePoint", | ||
0x013F: "PrimaryChromaticities", | ||
0x0211: "YCbCrCoefficients", | ||
0x0214: "ReferenceBlackWhite", | ||
0x0132: "DateTime", | ||
0x010E: "ImageDescription", | ||
0x010F: "Make", | ||
0x0110: "Model", | ||
0x0131: "Software", | ||
0x013B: "Artist", | ||
0x8298: "Copyright" | ||
}; | ||
var bigEnd, | ||
tags, tag, | ||
exifData, gpsData, | ||
tiffOffset = start + 6; | ||
var GPSTags = EXIF.GPSTags = { | ||
0x0000: "GPSVersionID", | ||
0x0001: "GPSLatitudeRef", | ||
0x0002: "GPSLatitude", | ||
0x0003: "GPSLongitudeRef", | ||
0x0004: "GPSLongitude", | ||
0x0005: "GPSAltitudeRef", | ||
0x0006: "GPSAltitude", | ||
0x0007: "GPSTimeStamp", | ||
0x0008: "GPSSatellites", | ||
0x0009: "GPSStatus", | ||
0x000A: "GPSMeasureMode", | ||
0x000B: "GPSDOP", | ||
0x000C: "GPSSpeedRef", | ||
0x000D: "GPSSpeed", | ||
0x000E: "GPSTrackRef", | ||
0x000F: "GPSTrack", | ||
0x0010: "GPSImgDirectionRef", | ||
0x0011: "GPSImgDirection", | ||
0x0012: "GPSMapDatum", | ||
0x0013: "GPSDestLatitudeRef", | ||
0x0014: "GPSDestLatitude", | ||
0x0015: "GPSDestLongitudeRef", | ||
0x0016: "GPSDestLongitude", | ||
0x0017: "GPSDestBearingRef", | ||
0x0018: "GPSDestBearing", | ||
0x0019: "GPSDestDistanceRef", | ||
0x001A: "GPSDestDistance", | ||
0x001B: "GPSProcessingMethod", | ||
0x001C: "GPSAreaInformation", | ||
0x001D: "GPSDateStamp", | ||
0x001E: "GPSDifferential" | ||
}; | ||
// test for TIFF validity and endianness | ||
if (file.getUint16(tiffOffset) == 0x4949) { | ||
bigEnd = false; | ||
} else if (file.getUint16(tiffOffset) == 0x4D4D) { | ||
bigEnd = true; | ||
} else { | ||
if (debug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"); | ||
return false; | ||
} | ||
var StringValues = EXIF.StringValues = { | ||
ExposureProgram: { | ||
0: "Not defined", | ||
1: "Manual", | ||
2: "Normal program", | ||
3: "Aperture priority", | ||
4: "Shutter priority", | ||
5: "Creative program", | ||
6: "Action program", | ||
7: "Portrait mode", | ||
8: "Landscape mode" | ||
}, | ||
MeteringMode: { | ||
0: "Unknown", | ||
1: "Average", | ||
2: "CenterWeightedAverage", | ||
3: "Spot", | ||
4: "MultiSpot", | ||
5: "Pattern", | ||
6: "Partial", | ||
255: "Other" | ||
}, | ||
LightSource: { | ||
0: "Unknown", | ||
1: "Daylight", | ||
2: "Fluorescent", | ||
3: "Tungsten (incandescent light)", | ||
4: "Flash", | ||
9: "Fine weather", | ||
10: "Cloudy weather", | ||
11: "Shade", | ||
12: "Daylight fluorescent (D 5700 - 7100K)", | ||
13: "Day white fluorescent (N 4600 - 5400K)", | ||
14: "Cool white fluorescent (W 3900 - 4500K)", | ||
15: "White fluorescent (WW 3200 - 3700K)", | ||
17: "Standard light A", | ||
18: "Standard light B", | ||
19: "Standard light C", | ||
20: "D55", | ||
21: "D65", | ||
22: "D75", | ||
23: "D50", | ||
24: "ISO studio tungsten", | ||
255: "Other" | ||
}, | ||
Flash: { | ||
0x0000: "Flash did not fire", | ||
0x0001: "Flash fired", | ||
0x0005: "Strobe return light not detected", | ||
0x0007: "Strobe return light detected", | ||
0x0009: "Flash fired, compulsory flash mode", | ||
0x000D: "Flash fired, compulsory flash mode, return light not detected", | ||
0x000F: "Flash fired, compulsory flash mode, return light detected", | ||
0x0010: "Flash did not fire, compulsory flash mode", | ||
0x0018: "Flash did not fire, auto mode", | ||
0x0019: "Flash fired, auto mode", | ||
0x001D: "Flash fired, auto mode, return light not detected", | ||
0x001F: "Flash fired, auto mode, return light detected", | ||
0x0020: "No flash function", | ||
0x0041: "Flash fired, red-eye reduction mode", | ||
0x0045: "Flash fired, red-eye reduction mode, return light not detected", | ||
0x0047: "Flash fired, red-eye reduction mode, return light detected", | ||
0x0049: "Flash fired, compulsory flash mode, red-eye reduction mode", | ||
0x004D: "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected", | ||
0x004F: "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected", | ||
0x0059: "Flash fired, auto mode, red-eye reduction mode", | ||
0x005D: "Flash fired, auto mode, return light not detected, red-eye reduction mode", | ||
0x005F: "Flash fired, auto mode, return light detected, red-eye reduction mode" | ||
}, | ||
SensingMethod: { | ||
1: "Not defined", | ||
2: "One-chip color area sensor", | ||
3: "Two-chip color area sensor", | ||
4: "Three-chip color area sensor", | ||
5: "Color sequential area sensor", | ||
7: "Trilinear sensor", | ||
8: "Color sequential linear sensor" | ||
}, | ||
SceneCaptureType: { | ||
0: "Standard", | ||
1: "Landscape", | ||
2: "Portrait", | ||
3: "Night scene" | ||
}, | ||
SceneType: { | ||
1: "Directly photographed" | ||
}, | ||
CustomRendered: { | ||
0: "Normal process", | ||
1: "Custom process" | ||
}, | ||
WhiteBalance: { | ||
0: "Auto white balance", | ||
1: "Manual white balance" | ||
}, | ||
GainControl: { | ||
0: "None", | ||
1: "Low gain up", | ||
2: "High gain up", | ||
3: "Low gain down", | ||
4: "High gain down" | ||
}, | ||
Contrast: { | ||
0: "Normal", | ||
1: "Soft", | ||
2: "Hard" | ||
}, | ||
Saturation: { | ||
0: "Normal", | ||
1: "Low saturation", | ||
2: "High saturation" | ||
}, | ||
Sharpness: { | ||
0: "Normal", | ||
1: "Soft", | ||
2: "Hard" | ||
}, | ||
SubjectDistanceRange: { | ||
0: "Unknown", | ||
1: "Macro", | ||
2: "Close view", | ||
3: "Distant view" | ||
}, | ||
FileSource: { | ||
3: "DSC" | ||
}, | ||
if (file.getUint16(tiffOffset+2, !bigEnd) != 0x002A) { | ||
if (debug) console.log("Not valid TIFF data! (no 0x002A)"); | ||
return false; | ||
} | ||
Components: { | ||
0: "", | ||
1: "Y", | ||
2: "Cb", | ||
3: "Cr", | ||
4: "R", | ||
5: "G", | ||
6: "B" | ||
} | ||
}; | ||
var firstIFDOffset = file.getUint32(tiffOffset+4, !bigEnd); | ||
function addEvent(element, event, handler) { | ||
if (element.addEventListener) { | ||
element.addEventListener(event, handler, false); | ||
} else if (element.attachEvent) { | ||
element.attachEvent("on" + event, handler); | ||
} | ||
} | ||
if (firstIFDOffset < 0x00000008) { | ||
if (debug) console.log("Not valid TIFF data! (First offset less than 8)", file.getUint32(tiffOffset+4, !bigEnd)); | ||
return false; | ||
} | ||
function imageHasData(img) { | ||
return !!img.exifdata; | ||
} | ||
tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd); | ||
function base64ToArrayBuffer(base64, contentType) { | ||
contentType = contentType || base64.match(/^data\:([^\;]+)\;base64,/mi)[1] || ''; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg' | ||
base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, ''); | ||
var binary = atob(base64); | ||
var len = binary.length; | ||
var buffer = new ArrayBuffer(len); | ||
var view = new Uint8Array(buffer); | ||
for (var i = 0; i < len; i++) { | ||
view[i] = binary.charCodeAt(i); | ||
} | ||
return buffer; | ||
} | ||
if (tags.ExifIFDPointer) { | ||
exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd); | ||
for (tag in exifData) { | ||
switch (tag) { | ||
case "LightSource" : | ||
case "Flash" : | ||
case "MeteringMode" : | ||
case "ExposureProgram" : | ||
case "SensingMethod" : | ||
case "SceneCaptureType" : | ||
case "SceneType" : | ||
case "CustomRendered" : | ||
case "WhiteBalance" : | ||
case "GainControl" : | ||
case "Contrast" : | ||
case "Saturation" : | ||
case "Sharpness" : | ||
case "SubjectDistanceRange" : | ||
case "FileSource" : | ||
exifData[tag] = StringValues[tag][exifData[tag]]; | ||
break; | ||
function objectURLToBlob(url, callback) { | ||
var http = new XMLHttpRequest(); | ||
http.open("GET", url, true); | ||
http.responseType = "blob"; | ||
http.onload = function (e) { | ||
if (this.status == 200 || this.status === 0) { | ||
callback(this.response); | ||
} | ||
}; | ||
http.send(); | ||
} | ||
case "ExifVersion" : | ||
case "FlashpixVersion" : | ||
exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]); | ||
break; | ||
function getImageData(img, callback) { | ||
function handleBinaryFile(binFile) { | ||
var data = findEXIFinJPEG(binFile); | ||
var iptcdata = findIPTCinJPEG(binFile); | ||
img.exifdata = data || {}; | ||
img.iptcdata = iptcdata || {}; | ||
if (callback) { | ||
callback.call(img); | ||
} | ||
} | ||
case "ComponentsConfiguration" : | ||
exifData[tag] = | ||
StringValues.Components[exifData[tag][0]] + | ||
StringValues.Components[exifData[tag][1]] + | ||
StringValues.Components[exifData[tag][2]] + | ||
StringValues.Components[exifData[tag][3]]; | ||
break; | ||
} | ||
tags[tag] = exifData[tag]; | ||
} | ||
} | ||
if (img.src) { | ||
if (/^data\:/i.test(img.src)) { | ||
// Data URI | ||
var arrayBuffer = base64ToArrayBuffer(img.src); | ||
handleBinaryFile(arrayBuffer); | ||
} else if (/^blob\:/i.test(img.src)) { | ||
// Object URL | ||
var fileReader = new FileReader(); | ||
fileReader.onload = function (e) { | ||
handleBinaryFile(e.target.result); | ||
}; | ||
objectURLToBlob(img.src, function (blob) { | ||
fileReader.readAsArrayBuffer(blob); | ||
}); | ||
} else { | ||
var http = new XMLHttpRequest(); | ||
http.onload = function () { | ||
if (this.status == 200 || this.status === 0) { | ||
handleBinaryFile(http.response); | ||
} else { | ||
throw "Could not load image"; | ||
} | ||
http = null; | ||
}; | ||
http.open("GET", img.src, true); | ||
http.responseType = "arraybuffer"; | ||
http.send(null); | ||
} | ||
} else if (window.FileReader && (img instanceof window.Blob || img instanceof window.File)) { | ||
var fileReader = new FileReader(); | ||
fileReader.onload = function (e) { | ||
if (debug) console.log("Got file of length " + e.target.result.byteLength); | ||
handleBinaryFile(e.target.result); | ||
}; | ||
if (tags.GPSInfoIFDPointer) { | ||
gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd); | ||
for (tag in gpsData) { | ||
switch (tag) { | ||
case "GPSVersionID" : | ||
gpsData[tag] = gpsData[tag][0] + | ||
"." + gpsData[tag][1] + | ||
"." + gpsData[tag][2] + | ||
"." + gpsData[tag][3]; | ||
break; | ||
} | ||
tags[tag] = gpsData[tag]; | ||
} | ||
} | ||
fileReader.readAsArrayBuffer(img); | ||
} | ||
} | ||
return tags; | ||
} | ||
function findEXIFinJPEG(file) { | ||
var dataView = new DataView(file); | ||
EXIF.getData = function(img, callback) { | ||
if ((img instanceof Image || img instanceof HTMLImageElement) && !img.complete) return false; | ||
if (debug) console.log("Got file of length " + file.byteLength); | ||
if (dataView.getUint8(0) != 0xFF || dataView.getUint8(1) != 0xD8) { | ||
if (debug) console.log("Not a valid JPEG"); | ||
return false; // not a valid jpeg | ||
} | ||
if (!imageHasData(img)) { | ||
getImageData(img, callback); | ||
} else { | ||
if (callback) { | ||
callback.call(img); | ||
} | ||
} | ||
return true; | ||
} | ||
var offset = 2, | ||
length = file.byteLength, | ||
marker; | ||
EXIF.getTag = function(img, tag) { | ||
if (!imageHasData(img)) return; | ||
return img.exifdata[tag]; | ||
} | ||
while (offset < length) { | ||
if (dataView.getUint8(offset) != 0xFF) { | ||
if (debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(offset)); | ||
return false; // not a valid marker, something is wrong | ||
} | ||
EXIF.getAllTags = function(img) { | ||
if (!imageHasData(img)) return {}; | ||
var a, | ||
data = img.exifdata, | ||
tags = {}; | ||
for (a in data) { | ||
if (data.hasOwnProperty(a)) { | ||
tags[a] = data[a]; | ||
} | ||
} | ||
return tags; | ||
} | ||
marker = dataView.getUint8(offset + 1); | ||
if (debug) console.log(marker); | ||
EXIF.pretty = function(img) { | ||
if (!imageHasData(img)) return ""; | ||
var a, | ||
data = img.exifdata, | ||
strPretty = ""; | ||
for (a in data) { | ||
if (data.hasOwnProperty(a)) { | ||
if (typeof data[a] == "object") { | ||
if (data[a] instanceof Number) { | ||
strPretty += a + " : " + data[a] + " [" + data[a].numerator + "/" + data[a].denominator + "]\r\n"; | ||
} else { | ||
strPretty += a + " : [" + data[a].length + " values]\r\n"; | ||
} | ||
} else { | ||
strPretty += a + " : " + data[a] + "\r\n"; | ||
} | ||
} | ||
} | ||
return strPretty; | ||
} | ||
// we could implement handling for other markers here, | ||
// but we're only looking for 0xFFE1 for EXIF data | ||
EXIF.readFromBinaryFile = function(file) { | ||
return findEXIFinJPEG(file); | ||
} | ||
if (marker == 225) { | ||
if (debug) console.log("Found 0xFFE1 marker"); | ||
if (true) { | ||
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() { | ||
return EXIF; | ||
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | ||
} | ||
}.call(this)); | ||
return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2); | ||
// offset += 2 + file.getShortAt(offset+2, true); | ||
} else { | ||
offset += 2 + dataView.getUint16(offset + 2); | ||
} | ||
} | ||
} | ||
function findIPTCinJPEG(file) { | ||
var dataView = new DataView(file); | ||
/***/ }, | ||
/* 4 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
if (debug) console.log("Got file of length " + file.byteLength); | ||
if (dataView.getUint8(0) != 0xFF || dataView.getUint8(1) != 0xD8) { | ||
if (debug) console.log("Not a valid JPEG"); | ||
return false; // not a valid jpeg | ||
} | ||
'use strict'; | ||
var offset = 2, | ||
length = file.byteLength; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var isFieldSegmentStart = function isFieldSegmentStart(dataView, offset) { | ||
return dataView.getUint8(offset) === 0x38 && dataView.getUint8(offset + 1) === 0x42 && dataView.getUint8(offset + 2) === 0x49 && dataView.getUint8(offset + 3) === 0x4D && dataView.getUint8(offset + 4) === 0x04 && dataView.getUint8(offset + 5) === 0x04; | ||
}; | ||
var _createClass = function () { | ||
function defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
}return function (Constructor, protoProps, staticProps) { | ||
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; | ||
}; | ||
}(); | ||
while (offset < length) { | ||
var _helper = __webpack_require__(5); | ||
if (isFieldSegmentStart(dataView, offset)) { | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
// Get the length of the name header (which is padded to an even number of bytes) | ||
var nameHeaderLength = dataView.getUint8(offset + 7); | ||
if (nameHeaderLength % 2 !== 0) nameHeaderLength += 1; | ||
// Check for pre photoshop 6 format | ||
if (nameHeaderLength === 0) { | ||
// Always 4 | ||
nameHeaderLength = 4; | ||
} | ||
var Rotate = function () { | ||
function Rotate() { | ||
_classCallCheck(this, Rotate); | ||
} | ||
var startOffset = offset + 8 + nameHeaderLength; | ||
var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength); | ||
_createClass(Rotate, null, [{ | ||
key: 'changeFile', | ||
value: function changeFile(elem_id) { | ||
var elem = document.getElementById(elem_id); | ||
return readIPTCData(file, startOffset, sectionLength); | ||
elem.onchange = function (e) { | ||
Object.keys(e.target.files).forEach(function (index) { | ||
var reader = new FileReader(); | ||
reader.onload = function (e) { | ||
(0, _helper.setImage)(e.target.result); | ||
}; | ||
reader.readAsDataURL(e.target.files[index]); | ||
}); | ||
}; | ||
} | ||
}]); | ||
break; | ||
} | ||
return Rotate; | ||
}(); | ||
// Not the marker, continue searching | ||
offset++; | ||
} | ||
} | ||
var IptcFieldMap = { | ||
0x78: 'caption', | ||
0x6E: 'credit', | ||
0x19: 'keywords', | ||
0x37: 'dateCreated', | ||
0x50: 'byline', | ||
0x55: 'bylineTitle', | ||
0x7A: 'captionWriter', | ||
0x69: 'headline', | ||
0x74: 'copyright', | ||
0x0F: 'category' | ||
}; | ||
function readIPTCData(file, startOffset, sectionLength) { | ||
var dataView = new DataView(file); | ||
var data = {}; | ||
var fieldValue, fieldName, dataSize, segmentType, segmentSize; | ||
var segmentStartPos = startOffset; | ||
while (segmentStartPos < startOffset + sectionLength) { | ||
if (dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos + 1) === 0x02) { | ||
segmentType = dataView.getUint8(segmentStartPos + 2); | ||
if (segmentType in IptcFieldMap) { | ||
dataSize = dataView.getInt16(segmentStartPos + 3); | ||
segmentSize = dataSize + 5; | ||
fieldName = IptcFieldMap[segmentType]; | ||
fieldValue = getStringFromDB(dataView, segmentStartPos + 5, dataSize); | ||
// Check if we already stored a value with this name | ||
if (data.hasOwnProperty(fieldName)) { | ||
// Value already stored with this name, create multivalue field | ||
if (data[fieldName] instanceof Array) { | ||
data[fieldName].push(fieldValue); | ||
} else { | ||
data[fieldName] = [data[fieldName], fieldValue]; | ||
} | ||
} else { | ||
data[fieldName] = fieldValue; | ||
} | ||
} | ||
} | ||
segmentStartPos++; | ||
} | ||
return data; | ||
} | ||
exports.default = Rotate; | ||
function readTags(file, tiffStart, dirStart, strings, bigEnd) { | ||
var entries = file.getUint16(dirStart, !bigEnd), | ||
tags = {}, | ||
entryOffset, | ||
tag, | ||
i; | ||
/***/ }, | ||
/* 5 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
for (i = 0; i < entries; i++) { | ||
entryOffset = dirStart + i * 12 + 2; | ||
tag = strings[file.getUint16(entryOffset, !bigEnd)]; | ||
if (!tag && debug) console.log("Unknown tag: " + file.getUint16(entryOffset, !bigEnd)); | ||
tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd); | ||
} | ||
return tags; | ||
} | ||
'use strict'; | ||
function readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd) { | ||
var type = file.getUint16(entryOffset + 2, !bigEnd), | ||
numValues = file.getUint32(entryOffset + 4, !bigEnd), | ||
valueOffset = file.getUint32(entryOffset + 8, !bigEnd) + tiffStart, | ||
offset, | ||
vals, | ||
val, | ||
n, | ||
numerator, | ||
denominator; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.appendNewImages = exports.rotateFromOrientation = exports.canvasResizeAndDrawImage = exports.getOrientation = exports.setImage = undefined; | ||
switch (type) { | ||
case 1: // byte, 8-bit unsigned int | ||
case 7: | ||
// undefined, 8-bit byte, value depending on field | ||
if (numValues == 1) { | ||
return file.getUint8(entryOffset + 8, !bigEnd); | ||
} else { | ||
offset = numValues > 4 ? valueOffset : entryOffset + 8; | ||
vals = []; | ||
for (n = 0; n < numValues; n++) { | ||
vals[n] = file.getUint8(offset + n); | ||
} | ||
return vals; | ||
} | ||
var _createClass = function () { | ||
function defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
}return function (Constructor, protoProps, staticProps) { | ||
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; | ||
}; | ||
}(); | ||
case 2: | ||
// ascii, 8-bit byte | ||
offset = numValues > 4 ? valueOffset : entryOffset + 8; | ||
return getStringFromDB(file, offset, numValues - 1); | ||
var _size = __webpack_require__(6); | ||
case 3: | ||
// short, 16 bit int | ||
if (numValues == 1) { | ||
return file.getUint16(entryOffset + 8, !bigEnd); | ||
} else { | ||
offset = numValues > 2 ? valueOffset : entryOffset + 8; | ||
vals = []; | ||
for (n = 0; n < numValues; n++) { | ||
vals[n] = file.getUint16(offset + 2 * n, !bigEnd); | ||
} | ||
return vals; | ||
} | ||
var _exifJs = __webpack_require__(3); | ||
case 4: | ||
// long, 32 bit int | ||
if (numValues == 1) { | ||
return file.getUint32(entryOffset + 8, !bigEnd); | ||
} else { | ||
vals = []; | ||
for (n = 0; n < numValues; n++) { | ||
vals[n] = file.getUint32(valueOffset + 4 * n, !bigEnd); | ||
} | ||
return vals; | ||
} | ||
var _exifJs2 = _interopRequireDefault(_exifJs); | ||
case 5: | ||
// rational = two long values, first is numerator, second is denominator | ||
if (numValues == 1) { | ||
numerator = file.getUint32(valueOffset, !bigEnd); | ||
denominator = file.getUint32(valueOffset + 4, !bigEnd); | ||
val = new Number(numerator / denominator); | ||
val.numerator = numerator; | ||
val.denominator = denominator; | ||
return val; | ||
} else { | ||
vals = []; | ||
for (n = 0; n < numValues; n++) { | ||
numerator = file.getUint32(valueOffset + 8 * n, !bigEnd); | ||
denominator = file.getUint32(valueOffset + 4 + 8 * n, !bigEnd); | ||
vals[n] = new Number(numerator / denominator); | ||
vals[n].numerator = numerator; | ||
vals[n].denominator = denominator; | ||
} | ||
return vals; | ||
} | ||
function _interopRequireDefault(obj) { | ||
return obj && obj.__esModule ? obj : { default: obj }; | ||
} | ||
case 9: | ||
// slong, 32 bit signed int | ||
if (numValues == 1) { | ||
return file.getInt32(entryOffset + 8, !bigEnd); | ||
} else { | ||
vals = []; | ||
for (n = 0; n < numValues; n++) { | ||
vals[n] = file.getInt32(valueOffset + 4 * n, !bigEnd); | ||
} | ||
return vals; | ||
} | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
case 10: | ||
// signed rational, two slongs, first is numerator, second is denominator | ||
if (numValues == 1) { | ||
return file.getInt32(valueOffset, !bigEnd) / file.getInt32(valueOffset + 4, !bigEnd); | ||
} else { | ||
vals = []; | ||
for (n = 0; n < numValues; n++) { | ||
vals[n] = file.getInt32(valueOffset + 8 * n, !bigEnd) / file.getInt32(valueOffset + 4 + 8 * n, !bigEnd); | ||
} | ||
return vals; | ||
} | ||
} | ||
} | ||
var Helper = function () { | ||
function Helper() { | ||
_classCallCheck(this, Helper); | ||
} | ||
function getStringFromDB(buffer, start, length) { | ||
var outstr = ""; | ||
for (n = start; n < start + length; n++) { | ||
outstr += String.fromCharCode(buffer.getUint8(n)); | ||
} | ||
return outstr; | ||
} | ||
_createClass(Helper, null, [{ | ||
key: 'setImage', | ||
function readEXIFData(file, start) { | ||
if (getStringFromDB(file, start, 4) != "Exif") { | ||
if (debug) console.log("Not valid EXIF data! " + getStringFromDB(file, start, 4)); | ||
return false; | ||
} | ||
/** | ||
* @param result_reader {string} base64 の string | ||
*/ | ||
value: function setImage(result_reader) { | ||
var img = new Image(); | ||
img.onload = function () { | ||
var canvas = document.createElement('canvas'); | ||
var ctx = canvas.getContext('2d'); | ||
img.re_width = img.width; | ||
img.re_height = img.height; | ||
var bigEnd, | ||
tags, | ||
tag, | ||
exifData, | ||
gpsData, | ||
tiffOffset = start + 6; | ||
var orientation = getOrientation(img); | ||
// test for TIFF validity and endianness | ||
if (file.getUint16(tiffOffset) == 0x4949) { | ||
bigEnd = false; | ||
} else if (file.getUint16(tiffOffset) == 0x4D4D) { | ||
bigEnd = true; | ||
} else { | ||
if (debug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"); | ||
return false; | ||
} | ||
if (orientation === 6) { | ||
// 縦画像だった場合スマートフォンでは幅・高さは横画像と認識されるため、 width height を手動で入れ替える必要あり | ||
img.re_height = img.width; | ||
img.re_width = img.height; | ||
} | ||
if (file.getUint16(tiffOffset + 2, !bigEnd) != 0x002A) { | ||
if (debug) console.log("Not valid TIFF data! (no 0x002A)"); | ||
return false; | ||
} | ||
canvasResizeAndDrawImage(img, canvas, ctx); | ||
var firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd); | ||
rotateFromOrientation(orientation, img, ctx, canvas); | ||
if (firstIFDOffset < 0x00000008) { | ||
if (debug) console.log("Not valid TIFF data! (First offset less than 8)", file.getUint32(tiffOffset + 4, !bigEnd)); | ||
return false; | ||
} | ||
appendNewImage(canvas); | ||
}; | ||
img.src = result_reader; | ||
} | ||
tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd); | ||
/** | ||
* @param img {elem} | ||
* @param canvas {elem} | ||
* @param ctx {canvas obj} | ||
*/ | ||
if (tags.ExifIFDPointer) { | ||
exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd); | ||
for (tag in exifData) { | ||
switch (tag) { | ||
case "LightSource": | ||
case "Flash": | ||
case "MeteringMode": | ||
case "ExposureProgram": | ||
case "SensingMethod": | ||
case "SceneCaptureType": | ||
case "SceneType": | ||
case "CustomRendered": | ||
case "WhiteBalance": | ||
case "GainControl": | ||
case "Contrast": | ||
case "Saturation": | ||
case "Sharpness": | ||
case "SubjectDistanceRange": | ||
case "FileSource": | ||
exifData[tag] = StringValues[tag][exifData[tag]]; | ||
break; | ||
}, { | ||
key: 'canvasResizeAndDrawImage', | ||
value: function canvasResizeAndDrawImage(img, canvas, ctx) { | ||
if (img.re_width > img.re_height) { | ||
var resize = img.re_height * (_size.max_size / img.re_width); | ||
canvas.width = _size.max_size; | ||
canvas.height = resize; | ||
ctx.drawImage(img, 0, 0, _size.max_size, resize); | ||
} else if (img.re_height > img.re_width) { | ||
var _resize = img.re_width * (_size.max_size / img.re_height); | ||
canvas.width = _resize; | ||
canvas.height = _size.max_size; | ||
ctx.drawImage(img, 0, 0, _resize, _size.max_size); | ||
} else { | ||
canvas.width = _size.max_size; | ||
canvas.height = _size.max_size; | ||
ctx.drawImage(img, 0, 0, _size.max_size, _size.max_size); | ||
} | ||
} | ||
case "ExifVersion": | ||
case "FlashpixVersion": | ||
exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]); | ||
break; | ||
/** | ||
* @param img {elem} | ||
*/ | ||
case "ComponentsConfiguration": | ||
exifData[tag] = StringValues.Components[exifData[tag][0]] + StringValues.Components[exifData[tag][1]] + StringValues.Components[exifData[tag][2]] + StringValues.Components[exifData[tag][3]]; | ||
break; | ||
} | ||
tags[tag] = exifData[tag]; | ||
} | ||
} | ||
}, { | ||
key: 'getOrientation', | ||
value: function getOrientation(img) { | ||
var orientation = void 0; | ||
_exifJs2.default.getData(img, function () { | ||
orientation = _exifJs2.default.getTag(img, 'Orientation'); | ||
}); | ||
return orientation; | ||
} | ||
if (tags.GPSInfoIFDPointer) { | ||
gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd); | ||
for (tag in gpsData) { | ||
switch (tag) { | ||
case "GPSVersionID": | ||
gpsData[tag] = gpsData[tag][0] + "." + gpsData[tag][1] + "." + gpsData[tag][2] + "." + gpsData[tag][3]; | ||
break; | ||
} | ||
tags[tag] = gpsData[tag]; | ||
} | ||
} | ||
/** | ||
* #container に append | ||
* @param canvas {elem} | ||
*/ | ||
return tags; | ||
} | ||
}, { | ||
key: 'appendNewImage', | ||
value: function appendNewImage(canvas) { | ||
var base_64 = canvas.toDataURL('image/jpeg'); | ||
var new_img = new Image(); | ||
new_img.setAttribute('src', base_64); | ||
var container = document.getElementById('container'); | ||
return container.appendChild(new_img); | ||
} | ||
EXIF.getData = function (img, callback) { | ||
if ((img instanceof Image || img instanceof HTMLImageElement) && !img.complete) return false; | ||
/** | ||
* for mobile | ||
* orientation があった場合に正しい角度で見せるように canvas を使って回転させる | ||
* @param orientation {number} | ||
* @param img {elem} | ||
* @param ctx {canvas obj} | ||
* @param canvas {elem} | ||
*/ | ||
if (!imageHasData(img)) { | ||
getImageData(img, callback); | ||
} else { | ||
if (callback) { | ||
callback.call(img); | ||
} | ||
} | ||
return true; | ||
}; | ||
}, { | ||
key: 'rotateFromOrientation', | ||
value: function rotateFromOrientation(orientation, img, ctx, canvas) { | ||
switch (orientation) { | ||
case 2: | ||
// horizontal flip | ||
ctx.translate(canvas.width, 0); | ||
ctx.scale(-1, 1); | ||
break; | ||
case 3: | ||
// 180° rotate left | ||
ctx.translate(canvas.width, canvas.height); | ||
ctx.rotate(Math.PI); | ||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height); | ||
break; | ||
case 4: | ||
// vertical flip | ||
ctx.translate(0, canvas.height); | ||
ctx.scale(1, -1); | ||
break; | ||
case 5: | ||
// vertical flip + 90 rotate right | ||
ctx.rotate(0.5 * Math.PI); | ||
ctx.scale(1, -1); | ||
break; | ||
case 6: | ||
// 90° rotate right | ||
ctx.rotate(0.5 * Math.PI); | ||
ctx.translate(0, -canvas.height); | ||
var img_ratio = img.re_height / img.re_width - 1; | ||
ctx.drawImage(img, 0, canvas.width * img_ratio, canvas.height, canvas.width); | ||
break; | ||
case 7: | ||
// horizontal flip + 90 rotate right | ||
ctx.rotate(0.5 * Math.PI); | ||
ctx.translate(canvas.width, -canvas.height); | ||
ctx.scale(-1, 1); | ||
break; | ||
case 8: | ||
// 90° rotate left | ||
ctx.rotate(-0.5 * Math.PI); | ||
ctx.translate(-canvas.width, 0); | ||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height); | ||
break; | ||
} | ||
} | ||
}]); | ||
EXIF.getTag = function (img, tag) { | ||
if (!imageHasData(img)) return; | ||
return img.exifdata[tag]; | ||
}; | ||
return Helper; | ||
}(); | ||
EXIF.getAllTags = function (img) { | ||
if (!imageHasData(img)) return {}; | ||
var a, | ||
data = img.exifdata, | ||
tags = {}; | ||
for (a in data) { | ||
if (data.hasOwnProperty(a)) { | ||
tags[a] = data[a]; | ||
} | ||
} | ||
return tags; | ||
}; | ||
exports.default = Helper; | ||
var setImage = Helper.setImage; | ||
var getOrientation = Helper.getOrientation; | ||
var canvasResizeAndDrawImage = Helper.canvasResizeAndDrawImage; | ||
var rotateFromOrientation = Helper.rotateFromOrientation; | ||
var appendNewImages = Helper.appendNewImages; | ||
exports.setImage = setImage; | ||
exports.getOrientation = getOrientation; | ||
exports.canvasResizeAndDrawImage = canvasResizeAndDrawImage; | ||
exports.rotateFromOrientation = rotateFromOrientation; | ||
exports.appendNewImages = appendNewImages; | ||
EXIF.pretty = function (img) { | ||
if (!imageHasData(img)) return ""; | ||
var a, | ||
data = img.exifdata, | ||
strPretty = ""; | ||
for (a in data) { | ||
if (data.hasOwnProperty(a)) { | ||
if (_typeof(data[a]) == "object") { | ||
if (data[a] instanceof Number) { | ||
strPretty += a + " : " + data[a] + " [" + data[a].numerator + "/" + data[a].denominator + "]\r\n"; | ||
} else { | ||
strPretty += a + " : [" + data[a].length + " values]\r\n"; | ||
} | ||
} else { | ||
strPretty += a + " : " + data[a] + "\r\n"; | ||
} | ||
} | ||
} | ||
return strPretty; | ||
}; | ||
/***/ }, | ||
/* 6 */ | ||
/***/ function(module, exports) { | ||
EXIF.readFromBinaryFile = function (file) { | ||
return findEXIFinJPEG(file); | ||
}; | ||
"use strict"; | ||
if (true) { | ||
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () { | ||
return EXIF; | ||
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | ||
} | ||
}).call(this); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var max_size = exports.max_size = 720; | ||
/***/ | ||
}, | ||
/* 3 */ | ||
/***/function (module, exports) { | ||
exports.default = max_size; | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var file_id = exports.file_id = 'file_image'; | ||
var max_size = exports.max_size = 720; | ||
var default_container_id = exports.default_container_id = 'container'; | ||
exports.default = { file_id: file_id, max_size: max_size, default_container_id: default_container_id }; | ||
/***/ | ||
} | ||
/******/]); | ||
/***/ } | ||
/******/ ]); |
@@ -7,2 +7,7 @@ module.exports = { | ||
'no-undef': 'off', | ||
'camelcase': 'off', | ||
'strict': 'off', | ||
'no-use-before-define': 'off', | ||
'no-param-reassign': 'off', | ||
'no-shadow': 'off', | ||
}, | ||
@@ -9,0 +14,0 @@ parserOptions: { |
{ | ||
"name": "exif-rotate-js", | ||
"version": "0.0.9", | ||
"description": "Simple use file API. You can use input file, show preview images.", | ||
"main": "lib/index.js", | ||
"version": "0.0.10", | ||
"description": "When you use input file, you can see preview images.", | ||
"main": "lib/exif-rotate.js", | ||
"scripts": { | ||
"start": "babel src --out-dir lib && webpack --watch", | ||
"build": "babel src --out-dir lib", | ||
"start": "webpack --watch", | ||
"babel": "babel src --out-dir lib", | ||
"linter": "eslint --ignore-path .gitignore src/", | ||
"build": "npm run babel && npm run linter", | ||
"prepublish": "npm run build" | ||
@@ -15,3 +17,3 @@ }, | ||
"author": "hanagejet", | ||
"license": "ISC", | ||
"license": "MIT", | ||
"dependencies": { | ||
@@ -25,6 +27,10 @@ "exif-js": "^2.1.1" | ||
"eslint": "^3.7.1", | ||
"eslint-config-airbnb": "^12.0.0", | ||
"eslint-config-airbnb-base": "^8.0.0", | ||
"eslint-config-defaults": "^9.0.0", | ||
"eslint-loader": "^1.5.0", | ||
"eslint-plugin-import": "^2.0.0", | ||
"watch": "^0.19.2", | ||
"webpack": "^1.13.2" | ||
} | ||
} |
# exif-rotate-js | ||
Simple use file API. You can use input file, show preview images. | ||
When you use input file, you can see preview images. | ||
@@ -8,3 +8,4 @@ ## WHAT'S THIS MODULE | ||
- preview on file upload images. | ||
- use file API correct to mobile. | ||
- use file API, correct to mobile. | ||
- resize image's file size and size. | ||
@@ -18,4 +19,4 @@ ## HOW IT'S WORKS | ||
```js | ||
var Rotate = require('exif-rotate-js'); | ||
Rotate.changeFile('{file_elem_id}'); | ||
var ExifRotate = require('exif-rotate-js'); | ||
ExifRotate.onChangeFile('{options}'); | ||
``` | ||
@@ -32,7 +33,20 @@ | ||
| ------------- |:--------:|:-------------:| | ||
| ChangeFile | String | Preview images. | | ||
| onChangeFile | Object | Preview images. Setting Options | | ||
## FEATURED | ||
## OPTIONS | ||
- edit `#container` id name | ||
- write max image size | ||
See `lib/configs.js` | ||
### onChangeFile | ||
#### elem_id | ||
- Type: string | ||
- Default: null | ||
#### max_size | ||
- Type: number | ||
- Default: 720 | ||
#### container_id | ||
- Type: string | ||
- Default: container |
@@ -1,3 +0,5 @@ | ||
import Rotate from './lib/rotate'; | ||
import ExifRotate from './lib/exif-rotate'; | ||
Rotate.changeFile('file_image'); | ||
ExifRotate.onChangeFile({ | ||
file_id: 'file_image', | ||
}); |
@@ -5,3 +5,3 @@ module.exports = { | ||
entry: { | ||
index: './src/rotate.js', | ||
'exif-rotate': './src/exif-rotate.js', | ||
sample: './sample.js', | ||
@@ -24,6 +24,2 @@ }, | ||
}, | ||
eslint: { | ||
configFile: '.eslintrc' | ||
}, | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
15
50
48345
11
1302
1