Skip to content

Image 图片像素滤镜

一张图片, 为其提供像素滤镜效果, 支持颜色数量压缩、抗锯齿去除、背景色保留、网格线绘制等功能

基础功能

通过 src 属性指定图片路径, 组件会在 Canvas 上渲染像素滤镜效果

TIP

当前组件提供 widthheight 来设置 Canvas 及组件盒子的宽高, 默认为图片的宽高。但由于缩放渲染问题, 宽高设置过小可能会导致图片模糊, 请酌情使用或按比例缩放

新增 scale 属性来设置图片缩放比例, 当原图尺寸过大时, 强烈建议设置 scale 控制

<template>
  <div class="px-image-container f-c">
    <image-compare
      src="/pixel-ui/images/Starbucks.png"
      width="395"
      height="400"
      :block-size="8"
      :color-count="18"
    />
  </div>
</template>

自定义参数

你可以通过调整 block-sizecolor-count 等属性来自定义像素滤镜的效果

<template>
  <div class="f-c mb-20">
    <px-text class="w-200" tag="div">BlockSize:{{ blockSize }}</px-text>
    <px-button icon="minus-solid" @click="decreaseBlock"></px-button>
    <px-button icon="plus-solid" @click="increaseBlock"></px-button>
  </div>
  <div class="f-c mb-20">
    <px-text class="w-200" tag="div">ColorCount:{{ colorCount }}</px-text>
    <px-button icon="minus-solid" @click="decreaseColor"></px-button>
    <px-button icon="plus-solid" @click="increaseColor"></px-button>
  </div>
  <div class="px-image-container f-c">
    <image-compare
      src="/pixel-ui/images/xtaffy.png"
      :block-size="blockSize"
      :color-count="colorCount"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const blockSize = ref(5)
const colorCount = ref(35)

const decreaseBlock = () => {
  blockSize.value = Math.max(blockSize.value - 1, 2)
}
const increaseBlock = () => {
  blockSize.value = Math.min(blockSize.value + 1, 10)
}
const decreaseColor = () => {
  colorCount.value = Math.max(colorCount.value - 1, 2)
}
const increaseColor = () => {
  colorCount.value = Math.min(colorCount.value + 1, 64)
}
</script>

网格模式

通过设置 showGrid 控制是否显示 canvas 网格

<template>
  <div class="f-c mb-20">
    <px-button @click="showGrid = !showGrid" type="sakura">grid</px-button>
  </div>
  <div class="px-image-container f-c">
    <image-compare
      src="/pixel-ui/images/xinlang.jpg"
      :block-size="4"
      :color-count="18"
      :show-grid="showGrid"
    />
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'

const showGrid = ref(true)
</script>

在线体验

提供在线演练场, 上传图片, 快速体验

<template>
  <div class="upload f-c mb-20">
    <px-button type="sakura" @click="uploadImg">
      Upload
      <px-icon icon="upload-alt-solid" color="#554562" />
    </px-button>
    <input
      ref="fileInputRef"
      type="file"
      accept="image/*"
      class="hidden"
      @change="handleFileChange"
    />
  </div>
  <div class="f-c mb-20">
    <px-button @click="showGrid = !showGrid" type="sakura">grid</px-button>
  </div>
  <div class="f-c mb-20">
    <px-text class="w-200" tag="div">Scale:{{ scale }}</px-text>
    <px-button icon="minus-solid" @click="decreaseScale"></px-button>
    <px-button icon="plus-solid" @click="increaseScale"></px-button>
  </div>
  <div class="f-c mb-20">
    <px-text class="w-200" tag="div">BlockSize:{{ blockSize }}</px-text>
    <px-button icon="minus-solid" @click="decreaseBlock"></px-button>
    <px-button icon="plus-solid" @click="increaseBlock"></px-button>
  </div>
  <div class="f-c mb-20">
    <px-text class="w-200" tag="div">ColorCount:{{ colorCount }}</px-text>
    <px-button icon="minus-solid" @click="decreaseColor"></px-button>
    <px-button icon="plus-solid" @click="increaseColor"></px-button>
  </div>
  <div class="px-image-container f-c">
    <image-compare
      :src="pxImageSrc"
      :block-size="blockSize"
      :color-count="colorCount"
      :show-grid="showGrid"
      :scale="scale"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const blockSize = ref(4)
const colorCount = ref(36)
const scale = ref(0.5)
const step = 0.1

const decreaseScale = () => {
  scale.value = Math.max(0.1, Math.round((scale.value - step) * 10) / 10)
}

const increaseScale = () => {
  scale.value = Math.min(1.0, Math.round((scale.value + step) * 10) / 10)
}
const decreaseBlock = () => {
  blockSize.value = Math.max(blockSize.value - 1, 2)
}
const increaseBlock = () => {
  blockSize.value = Math.min(blockSize.value + 1, 10)
}
const decreaseColor = () => {
  colorCount.value = Math.max(colorCount.value - 1, 2)
}
const increaseColor = () => {
  colorCount.value = Math.min(colorCount.value + 1, 64)
}

const showGrid = ref(true)
const pxImageSrc = ref('/pixel-ui/images/Starbucks.png')

const fileInputRef = ref<HTMLInputElement>()
const uploadImg = () => {
  fileInputRef.value?.click()
}

const handleFileChange = (e: Event) => {
  const files = (e.target as HTMLInputElement).files
  if (files && files.length > 0) {
    const file = files[0]
    const url = URL.createObjectURL(file)
    pxImageSrc.value = url
  }
}
</script>

API_Table插件测试

DANGER

该插件基于 markdown-it 开发, 解析组件 types.ts 文件生成 API 表格, 测试中

Image API

Props

NameDescriptionTypeDefault
width宽度(px)number | string-
height高度(px)number | string-
src待转换图片urlstring-
blockSize块大小number | string2
colorCount颜色数量number | string32
showGrid是否显示网格booleanfalse
scale缩放比例,原图尺寸过大时强烈建议设置number | string1

Events

NameDescriptionType
ready图片处理完成function

Expose

NameDescriptionType
getSize获取处理后 canvas 尺寸function
render渲染图片function
本站访客数 人次 本站总访问量