|
|
@ -1,27 +1,74 @@
|
|
|
|
<script setup lang="ts">
|
|
|
|
<script setup lang="ts">
|
|
|
|
import { onMounted, ref } from 'vue';
|
|
|
|
import { onMounted, ref } from 'vue';
|
|
|
|
import { grayScale } from "../processing/gray-scale.ts";
|
|
|
|
import { blackAndWhite, grayScale } from '../processing/gray-scale.ts';
|
|
|
|
import ImageCollection from "./ImageCollection.vue";
|
|
|
|
import ImageCollection from './ImageCollection.vue';
|
|
|
|
|
|
|
|
|
|
|
|
const canvas = ref<HTMLCanvasElement | null>(null)
|
|
|
|
const canvas = ref<HTMLCanvasElement | null>(null);
|
|
|
|
|
|
|
|
const currentWidth = ref(100);
|
|
|
|
|
|
|
|
const currentHeight = ref(100);
|
|
|
|
|
|
|
|
let img: HTMLImageElement;
|
|
|
|
let ctx: CanvasRenderingContext2D;
|
|
|
|
let ctx: CanvasRenderingContext2D;
|
|
|
|
onMounted(() => {
|
|
|
|
onMounted(() => {
|
|
|
|
ctx = canvas.value!.getContext('2d')!;
|
|
|
|
ctx = canvas.value!.getContext('2d')!;
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
function onSelected(img: HTMLImageElement): void {
|
|
|
|
function onSelected(image: HTMLImageElement): void {
|
|
|
|
ctx.drawImage(img, 0, 0);
|
|
|
|
canvas.value!.width = image.width;
|
|
|
|
const imageData = ctx.getImageData(0, 0, img.width, img.height);
|
|
|
|
canvas.value!.height = image.height;
|
|
|
|
|
|
|
|
ctx.drawImage(image, 0, 0);
|
|
|
|
|
|
|
|
img = image;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function grayScaleApply() {
|
|
|
|
|
|
|
|
const imageData = ctx.getImageData(0, 0, canvas.value!.width, canvas.value!.height);
|
|
|
|
const pixels = imageData.data;
|
|
|
|
const pixels = imageData.data;
|
|
|
|
grayScale(pixels);
|
|
|
|
grayScale(pixels);
|
|
|
|
ctx.putImageData(imageData, 0, 0);
|
|
|
|
ctx.putImageData(imageData, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function blackAndWhiteApply() {
|
|
|
|
|
|
|
|
const imageData = ctx.getImageData(0, 0, canvas.value!.width, canvas.value!.height);
|
|
|
|
|
|
|
|
const pixels = imageData.data;
|
|
|
|
|
|
|
|
blackAndWhite(pixels);
|
|
|
|
|
|
|
|
ctx.putImageData(imageData, 0, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function onChangeSlideWidth() {
|
|
|
|
|
|
|
|
const width = currentWidth.value / 100 * img.width;
|
|
|
|
|
|
|
|
canvas.value!.width = width;
|
|
|
|
|
|
|
|
ctx.drawImage(img, 0, 0, width, canvas.value!.height);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function onChangeSlideHeight() {
|
|
|
|
|
|
|
|
const height = currentHeight.value / 100 * img.height;
|
|
|
|
|
|
|
|
canvas.value!.height = height;
|
|
|
|
|
|
|
|
ctx.drawImage(img, 0, 0, canvas.value!.width, height);
|
|
|
|
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<template>
|
|
|
|
<div class="editor">
|
|
|
|
<div class="editor">
|
|
|
|
<ImageCollection @selected="onSelected" />
|
|
|
|
<ImageCollection @selected="onSelected" />
|
|
|
|
<canvas ref="canvas" width="500" height="500"></canvas>
|
|
|
|
<div class="working-area">
|
|
|
|
|
|
|
|
<div class="options">
|
|
|
|
|
|
|
|
<button @click="blackAndWhiteApply">
|
|
|
|
|
|
|
|
Black and white
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button @click="grayScaleApply">
|
|
|
|
|
|
|
|
Gray-scale
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="inner">
|
|
|
|
|
|
|
|
<input v-model="currentHeight" type="range" min="1" max="200" value="100" orient="vertical" @change="onChangeSlideHeight">
|
|
|
|
|
|
|
|
<div class="preview">
|
|
|
|
|
|
|
|
<canvas ref="canvas"></canvas>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="controls">
|
|
|
|
|
|
|
|
<input id="image-width" v-model="currentWidth" type="range" min="1" max="200" @change="onChangeSlideWidth">
|
|
|
|
|
|
|
|
<output for="image-width">{{ currentWidth }}%</output>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
@ -29,8 +76,33 @@ function onSelected(img: HTMLImageElement): void {
|
|
|
|
.editor {
|
|
|
|
.editor {
|
|
|
|
display: flex;
|
|
|
|
display: flex;
|
|
|
|
box-shadow: 0 0 2px 2px #1a1a1a;
|
|
|
|
box-shadow: 0 0 2px 2px #1a1a1a;
|
|
|
|
|
|
|
|
padding: 8px;
|
|
|
|
|
|
|
|
height: calc(100vh - 96px);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
canvas {
|
|
|
|
.working-area {
|
|
|
|
flex-grow: 1;
|
|
|
|
flex-grow: 1;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.inner {
|
|
|
|
|
|
|
|
flex-grow: 1;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.preview {
|
|
|
|
|
|
|
|
flex-grow: 1;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
canvas {
|
|
|
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
|
|
|
max-height: 100%;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
input[type=range][orient=vertical] {
|
|
|
|
|
|
|
|
appearance: slider-vertical;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
output {
|
|
|
|
|
|
|
|
vertical-align: top;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</style>
|
|
|
|