jonigata commited on
Commit
9ae3428
1 Parent(s): 5f60e23

insert pose meta data into png

Browse files
Files changed (2) hide show
  1. app.py +1 -1
  2. static/poseEditor.js +153 -0
app.py CHANGED
@@ -129,7 +129,7 @@ Points to note for pseudo-3D rotation: When performing pseudo-3D rotation on the
129
  - "shift + drag" to **rotate** (move right first, release shift, then up or down)
130
  - "space + drag" to **range-move**
131
  - "[", "]" or mouse "Alt + wheel" to shrink or expand **range**
132
- - "ctrl + z", "shift + ctrl + z" to **undo**, **redo**
133
  - "ctrl + E" **add** new person
134
  - "Q + click" to **delete** person
135
  - "X + drag" to **x-axis** pseudo-3D rotation
 
129
  - "shift + drag" to **rotate** (move right first, release shift, then up or down)
130
  - "space + drag" to **range-move**
131
  - "[", "]" or mouse "Alt + wheel" to shrink or expand **range**
132
+ - "ctrl + Z", "shift + ctrl + Z" to **undo**, **redo**
133
  - "ctrl + E" **add** new person
134
  - "Q + click" to **delete** person
135
  - "X + drag" to **x-axis** pseudo-3D rotation
static/poseEditor.js CHANGED
@@ -578,6 +578,7 @@ function importPose(jsonData) {
578
  Redraw();
579
  }
580
 
 
581
  function savePose() {
582
  const canvasUrl = canvas.toDataURL();
583
 
@@ -593,3 +594,155 @@ function savePose() {
593
  var [candidate, subset] = poseDataToCandidateAndSubset(poseData);
594
  return {candidate: candidate, subset: subset};
595
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
578
  Redraw();
579
  }
580
 
581
+ /*
582
  function savePose() {
583
  const canvasUrl = canvas.toDataURL();
584
 
 
594
  var [candidate, subset] = poseDataToCandidateAndSubset(poseData);
595
  return {candidate: candidate, subset: subset};
596
  }
597
+ */
598
+
599
+ // crc32
600
+ // CRC32を初期化
601
+ function initCrc32Table() {
602
+ const crcTable = new Uint32Array(256);
603
+ for (let i = 0; i < 256; i++) {
604
+ let c = i;
605
+ for (let j = 0; j < 8; j++) {
606
+ c = (c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1);
607
+ }
608
+ crcTable[i] = c;
609
+ }
610
+ return crcTable;
611
+ }
612
+
613
+ // データのCRC32を計算
614
+ function getCrc32(data, crc=0) {
615
+ const crcTable = initCrc32Table();
616
+ crc = (crc ^ 0xFFFFFFFF) >>> 0;
617
+ for (let i = 0; i < data.length; i++) {
618
+ crc = crcTable[(crc ^ data[i]) & 0xFF] ^ (crc >>> 8);
619
+ }
620
+ return (crc ^ 0xFFFFFFFF) >>> 0;
621
+ }
622
+
623
+ function stringToUint8Array(str) {
624
+ var arr = new Uint8Array(str.length);
625
+ for (var i = 0; i < str.length; i++) {
626
+ arr[i] = str.charCodeAt(i);
627
+ }
628
+ return arr;
629
+ }
630
+
631
+ function base64ToUint8Array(base64Str) {
632
+ return stringToUint8Array(atob(base64Str));
633
+ }
634
+
635
+ function visitPng(png, type) {
636
+ var dataLength;
637
+ var chunkType;
638
+ var nextChunkPos;
639
+ var Signature = String.fromCharCode(137, 80, 78, 71, 13, 10, 26, 10);
640
+ var rpos = 0;
641
+
642
+ // シグネチャの確認
643
+ if (String.fromCharCode.apply(null, png.subarray(rpos, rpos += 8)) !== Signature) {
644
+ throw new Error('invalid signature');
645
+ }
646
+
647
+ // チャンクの探索
648
+ while (rpos < png.length) {
649
+ dataLength = (
650
+ (png[rpos++] << 24) |
651
+ (png[rpos++] << 16) |
652
+ (png[rpos++] << 8) |
653
+ (png[rpos++] )
654
+ ) >>> 0;
655
+
656
+ nextChunkPos = rpos + dataLength + 8;
657
+
658
+ chunkType = String.fromCharCode.apply(null, png.subarray(rpos, rpos += 4));
659
+
660
+ if (chunkType === type) {
661
+ return [rpos - 8, dataLength, nextChunkPos];
662
+ }
663
+
664
+ rpos = nextChunkPos;
665
+ }
666
+ }
667
+
668
+ function createChunk(type, data) {
669
+ var dataLength = data.length;
670
+ var chunk = new Uint8Array(4 + 4 + dataLength + 4);
671
+ var type = stringToUint8Array(type);
672
+ var pos = 0;
673
+
674
+ // length
675
+ chunk[pos++] = (dataLength >> 24) & 0xff;
676
+ chunk[pos++] = (dataLength >> 16) & 0xff;
677
+ chunk[pos++] = (dataLength >> 8) & 0xff;
678
+ chunk[pos++] = (dataLength ) & 0xff;
679
+
680
+ // type
681
+ chunk[pos++] = type[0];
682
+ chunk[pos++] = type[1];
683
+ chunk[pos++] = type[2];
684
+ chunk[pos++] = type[3];
685
+
686
+ // data
687
+ for (let i = 0; i < dataLength; ++i) {
688
+ chunk[pos++] = data[i];
689
+ }
690
+
691
+ //crc
692
+ initCrc32Table();
693
+ let crc = getCrc32(type);
694
+ crc = getCrc32(data, crc);
695
+ chunk[pos++] = (crc >> 24) & 0xff;
696
+ chunk[pos++] = (crc >> 16) & 0xff;
697
+ chunk[pos++] = (crc >> 8) & 0xff;
698
+ chunk[pos++] = (crc ) & 0xff;
699
+
700
+ return chunk;
701
+ }
702
+
703
+ function insertChunk(destBuffer, sourceBuffer, rpos, chunk) {
704
+ var pos = 0;
705
+
706
+ // IDAT チャンクの前までコピー
707
+ destBuffer.set(sourceBuffer.subarray(0, rpos), pos);
708
+ pos += rpos;
709
+
710
+ // hoGe チャンクをコピー
711
+ destBuffer.set(chunk, pos);
712
+ pos += chunk.length;
713
+
714
+ // IDAT チャンク以降をコピー
715
+ destBuffer.set(sourceBuffer.subarray(rpos), pos);
716
+ }
717
+
718
+ function mergeCanvasWithPose(keyword, content) {
719
+ const canvasUrl = canvas.toDataURL();
720
+
721
+ var insertion = stringToUint8Array(`${keyword}\0${content}`);
722
+ var chunk = createChunk("tEXt", insertion);
723
+ var sourceBuffer = base64ToUint8Array(canvasUrl.split(',')[1]);
724
+ var destBuffer = new Uint8Array(sourceBuffer.length + insertion.length + 12);
725
+
726
+ var [rpos, dataLength, nextChunkPos] = visitPng(sourceBuffer, "IHDR");
727
+ insertChunk(destBuffer, sourceBuffer, nextChunkPos, chunk);
728
+
729
+ var blob = new Blob([destBuffer], {type: "image/png"});
730
+ var url = URL.createObjectURL(blob);
731
+ return url;
732
+ }
733
+
734
+ function savePose() {
735
+ var [candidate, subset] = poseDataToCandidateAndSubset(poseData);
736
+ let jsonData = {candidate: candidate, subset: subset};
737
+
738
+ var url = mergeCanvasWithPose("pose", JSON.stringify(jsonData));
739
+
740
+ const createEl = document.createElement('a');
741
+ createEl.href = url;
742
+
743
+ // This is the name of our downloaded file
744
+ createEl.download = "pose.png";
745
+
746
+ createEl.click();
747
+ createEl.remove();
748
+ }