-
Notifications
You must be signed in to change notification settings - Fork 0
/
ImagePublisher.js
157 lines (139 loc) · 5.7 KB
/
ImagePublisher.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
* ImagePublisher.js
* K Miyano (miyacorata)
*/
let image = new Image();
let preview = document.getElementById('preview');
let context = preview.getContext('2d');
const font = ' "VL PGothic", "Meiryo", sans';
// EXIFタグを追加
EXIF.Tags[0xA434] = 'LensModel';
// preview更新関数
const updatePreview = () => {
// 画像を読み込み
const imageInput = document.getElementById('image-input').files[0];
if (imageInput === undefined) {
return;
}
// ファイル名を表示
document.getElementById('file-name').innerText = imageInput.name;
// EXIF解析
EXIF.getData(imageInput, function() {
let exifData = {};
console.dir(EXIF.getAllTags(this));
// 撮影日
const dateRaw = String(EXIF.getTag(this, 'DateTimeOriginal') ?? '').split(' ');
document.getElementById('DateTimeOriginal').innerText = exifData['DateTimeOriginal']
= dateRaw[0].replaceAll(':','/');
// シャッタースピード
const exposureTime = EXIF.getTag(this, 'ExposureTime');
document.getElementById('ExposureTime').innerText = exifData['ExposureTime'] = exposureTime < 1
? (exposureTime.numerator + '/' + exposureTime.denominator)
: (exposureTime + 's');
// 単純な値
const commonTags = [
'Model',
'LensModel',
'FocalLength',
'FNumber',
'ISOSpeedRatings',
];
// 単位とか
const prefix = {
'FNumber': 'F',
}
const suffix = {
'FocalLength': 'mm',
}
commonTags.map((tag) => {
document.getElementById(tag).innerText = exifData[tag] =
(prefix[tag] ?? '') + (EXIF.getTag(this, tag) ?? '') + (suffix[tag] ?? '');
});
// canvas#preview に画像を表示
const reader = new FileReader();
reader.readAsDataURL(imageInput);
reader.addEventListener('load', () => {
image.src = reader.result;
});
image.addEventListener('load', () => {
// 画像サイズに応じてCanvasサイズを変更
preview.height = image.height / (image.width / 1920);
// 画像を描画
context.drawImage(image, 0, 0, preview.width, preview.height);
// テキストの初期設定
context.fillStyle = 'white';
context.textAlign = 'right';
context.textBaseline = 'ideographic';
// ドロップシャドウを設定
context.shadowColor = 'rgba(0,0,0,0.7)';
context.shadowBlur = 10;
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.font = '20px' + font;
context.fillText('hoge', 0,0);
// 文字列表示位置の初期化
var textY = preview.height - 20;
const lineHeight = 27;
// 撮影情報と作者名を出力
let summary = [];
summary.push(document.getElementById('description').value);
summary.push(exifData['DateTimeOriginal'] + ' ' + document.getElementById('author').value);
summary.push(
exifData['Model'] + ' - ' + exifData['LensModel'] + (exifData['LensModel'] ? ' - ' : ' ') +
exifData['FocalLength'] + ' ' + exifData['FNumber'] + ' ' +
exifData['ExposureTime'] + ' ISO' + exifData['ISOSpeedRatings']
);
console.dir(summary);
summary.reverse().map((text) => {
if (text.length === 0) return;
context.fillText(text, 1890, textY, 1000);
textY -= lineHeight;
});
context.font = '30px' + font;
context.fillText(document.getElementById('title').value, 1890, textY - 6, 1000);
context.font = '20px' + font;
});
});
};
const saveImage = function () {
const a = document.createElement('a');
const title = document.getElementById('title').value;
switch (this.type) {
case 'png':
a.href = preview.toDataURL('image/png', 100);
a.download = (title ? title : 'image')+'.png';
break;
case 'jpg':
a.href = preview.toDataURL('image/jpeg', 100);
a.download = (title ? title : 'image')+'.jpg';
break;
default:
throw '画像タイプが正しく指定できていないかもしれません';
}
a.click();
}
const copyImage = function () {
try {
preview.toBlob((blob) => {
const data = new ClipboardItem({
'image/png': blob
});
navigator.clipboard.write([data]).then(() => {
document.getElementById('cb-copy').classList.add('is-success');
setTimeout(() => {
document.getElementById('cb-copy').classList.remove('is-success');
}, 1000);
});
}, 'image/png', 100);
} catch (e) {
alert("何らかのエラーが発生しました。\n開発者ツールで詳細を確認できます。");
console.dir(e);
}
}
document.getElementById('image-input').addEventListener('change', updatePreview);
document.getElementById('author').addEventListener('change', updatePreview);
document.getElementById('title').addEventListener('change', updatePreview);
document.getElementById('description').addEventListener('change', updatePreview);
document.getElementById('png-save').addEventListener('click', {handleEvent: saveImage, type: 'png'});
document.getElementById('jpg-save').addEventListener('click', {handleEvent: saveImage, type: 'jpg'});
document.getElementById('cb-copy').addEventListener('click', copyImage);