Skip to content

Commit

Permalink
Implement button for importing a image
Browse files Browse the repository at this point in the history
Merge pull request #88 from haroldo-ok/export-image
  • Loading branch information
haroldo-ok authored Jun 12, 2024
2 parents 72716a8 + 80a7563 commit 1db4ca4
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 39 deletions.
75 changes: 36 additions & 39 deletions src/components/PixelEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,36 +50,31 @@

</v-row>
<v-row>
<v-btn
title="Copy"
@click="() => handleCopy()"
>
<v-icon>mdi-content-copy</v-icon>
</v-btn>
<v-btn
title="Paste"
@click="() => handlePaste()"
>
<v-icon>mdi-content-paste</v-icon>
</v-btn>
<v-btn
title="Export to image"
@click="() => handleExportImage()"
>
<v-icon>mdi-export</v-icon>
</v-btn>

<v-btn
title="Import from image"
@click="() => handleImportImage()"
>
<v-icon>mdi-import</v-icon>
</v-btn>
</v-row>
</v-col>
</v-card-actions>
</v-card>
</template>
<script>
import {PixelEditor, Pencil} from '@curtishughes/pixel-editor';
import {debounce} from 'lodash';
import {chunk, debounce} from 'lodash';
import {saveAs} from 'file-saver';
import {isMatrixEqual} from '../utils/array';
import {loadImageFromFile, openFileDialog} from '../utils/file';
import {createResizedCanvas} from '../utils/image';
export default {
props: {
Expand Down Expand Up @@ -117,31 +112,6 @@ export default {
}
}, 300),
handleCopy() {
const pixels = this.getPixels();
const text = pixels.map((row) => row.map((pixel) => pixel ? 'X' : '.')).join('\n');
// Adapted from https://stackoverflow.com/a/25275151/679240
const input = document.createElement('textarea');
document.body.appendChild(input);
input.value = text;
input.focus();
input.select();
document.execCommand('Copy');
input.remove();
},
handlePaste() {
// Adapted from https://stackoverflow.com/a/25275151/679240
const input = document.createElement('textarea');
document.body.appendChild(input);
input.focus();
input.select();
document.execCommand('Paste');
console.info('Pasted text', input.value);
input.remove();
},
handleExportImage() {
// Adapted from https://stackoverflow.com/a/28305948/679240
Expand All @@ -162,6 +132,33 @@ export default {
});
},
handleImportImage() {
openFileDialog('image/*')
.then(loadImageFromFile)
.then((img) => {
const canvas = createResizedCanvas(img, this.editor.width, this.editor.height);
// Adapted from https://stackoverflow.com/a/667074/679240
// Get the CanvasPixelArray from the given coordinates and dimensions.
const imageData = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
const imgPixels = imageData.data;
// Loop over each pixel
const pixelValues = [];
for (let i = 0, n = imgPixels.length; i < n; i += 4) {
const r = imgPixels[i]; // red
const g = imgPixels[i + 1]; // green
const b = imgPixels[i + 2]; // blue
// i+3 is alpha (the fourth element)
pixelValues.push((r + g + b) / 3);
}
const pixels = chunk(pixelValues.map((v) => v > 32 ? 1 : 0), canvas.width);
this.setPixels(pixels);
});
},
createEmptyPixelMatrix() {
return new Array(this.height).fill(0).map(() => new Array(this.width).fill(0));
},
Expand Down
28 changes: 28 additions & 0 deletions src/utils/file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export const openFileDialog = (accept) => new Promise((resolve, reject) => {
// Adapted from https://stackoverflow.com/a/72664569/679240

const input = document.createElement('input');
input.type = 'file';
input.setAttribute('accept', accept);
input.onchange = function(event) {
resolve(this.files[0]);
};
input.click();
});

export const loadImageFromFile = (file) => new Promise((resolve, reject) => {
// Adapted from https://stackoverflow.com/a/33112602/679240
const reader = new FileReader();
// load to image to get it's width/height
const img = new Image();
img.onload = function() {
resolve(img);
};
img.onerror = reject;
// this is to setup loading the image
reader.onloadend = () => {
img.src = reader.result;
};
// this is to read the file
reader.readAsDataURL(file);
});
10 changes: 10 additions & 0 deletions src/utils/image.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const createResizedCanvas = (img, width, height) => {
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;

const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height);

return canvas;
};

0 comments on commit 1db4ca4

Please sign in to comment.