leafer-ui icon indicating copy to clipboard operation
leafer-ui copied to clipboard

关于 clip 导出的一些疑问

Open mozbia opened this issue 4 months ago • 8 comments

事情是这样的: 大概一两个月前,有用户反馈,HDR JPG照片使用 clip 导出,然后合并成一张图片,会有白线。 如下图: Image

仔细观察,发现白线似乎是一些带透明度像素组成。

于是我通过设置导出参数 trim = true 解决了该问题。

最近 1.9.1 和 1.9.7 版本发现,设置 trim = true 不能解决了。 于是仔细看了导出文档, 我尝试加上 padding : -0.5, 居然能解决了

不知道为啥😂,虽然解决了。

for (let i = 0; i < chunks.length; i++) { const ret = await page.export(realType, { quality, blob: useLazyvaStore().exportConfig.blob, clip: { ...chunks[i], width: w, height: h }, relative: "local", trim: true, padding: -0.5, }) }

mozbia avatar Sep 12 '25 06:09 mozbia

估计是 w 或 h 存在小数造成的,可以打印看看

leaferjs avatar Sep 12 '25 06:09 leaferjs

小数确实是有。 我记得之前试过,Math.floor 取整,然后再 clip, 也不行。 一直是同一张照片测试的。

以前 trim 可以解决该问题,现在通过 padding 可以解决, 虽然不太了解padding 的具体工作逻辑, 但是我感觉是负数的 padding 可能会缩小导出时的范围。

mozbia avatar Sep 12 '25 06:09 mozbia

如果是小数的话,应该是出现黑线才对,因为合并的画布是黑色的。 我看看啥时候能整个例子,看看能重现不。

mozbia avatar Sep 12 '25 06:09 mozbia

好的

leaferjs avatar Sep 12 '25 08:09 leaferjs

重现了,大佬。 该问题在移动端 chrome 出现, 移动端 safari、pc chrome 、pc safari 均没问题。 现象如下: Image

clip 坐标、宽高均是整数。

代码:

import { Box, App, version, Image as LeaferImage, ImageEvent, Platform, } from 'leafer-ui'

import '@leafer-in/editor' import '@leafer-in/viewport' import '@leafer-in/flow' import '@leafer-in/export' import '@leafer-in/resize' import '@leafer-in/state' import '@leafer-in/text-editor' import { Flow } from '@leafer-in/flow'

Platform.fullImageShadow = true console.log(version) window.onload = () => { document.body.style.background = 'black' const container = document.createElement('div') container.style.display = 'flex' container.style.flexDirection = 'column'

const div = document.createElement('div') const canvas = document.createElement('canvas') div.setAttribute('id', 'canvas') div.style.width = '500px' div.style.height = '500px'

canvas.style.width = '500px' canvas.style.height = '500px'

const context = canvas.getContext('2d')

container.append(div) container.append(canvas) document.documentElement.append(container)

const leafer = new App({ view: 'canvas', usePartRender: true, pointer: { preventDefault: false, preventDefaultMenu: true, }, fill: 'gray', touch: { preventDefault: true, },

// zoom:{
//   disabled:true,
// },

tree: { type: 'design' },

}) const url = 'https://lazyva.com/p11.jpg' // hdr jpg 该照片 clip 导出合并后 有线条 , 下面照片则没问题 // const url = 'https://images.unsplash.com/photo-1590418606746-018840f9cd0f?q=80&w=987&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D' const image1 = new LeaferImage({ width: 886, height: 590, url: url, })

const spreadShadowBox = new Box({ flow: true, fill: 'yellow', children: [image1], overflow: 'hide', stroke: 'red', strokeAlign: 'outside', strokeWidth: 0, shadow: { x: 0, y: 20, blur: 20, spread: -10, color: '#000', }, })

const box1 = new Box({ flow: true, padding: 20, fill: 'white', overflow: 'hide', children: [spreadShadowBox], })

const flowBox1 = new Flow({ flowWrap: true, gap: 0 }) const flowContainer = new Flow({ gap: 100, padding: 100, overflow: 'show' }) leafer.tree.scale = 0.1

flowContainer.addMany(box1, flowBox1) leafer.tree.addMany(flowContainer)

image1.on(ImageEvent.LOADED, () => { // const scale = 2000 / 886 // box1.scale = 2 const bounds = box1.getBounds('stroke', 'local')

flowBox1.width = bounds.width + 100 * 2
flowBox1.height = bounds.height + 100 * 2
canvas.width = flowBox1.width
canvas.height = flowBox1.height

const w = Math.floor(bounds.width / 4)
const h = Math.floor(bounds.height / 4)
const chunks = Array.from({ length: 16 }, (_, i) => ({
  x: (i % 4) * w,
  y: Math.floor(i / 4) * h,
  width: w,
  height: h,
}))

alert(JSON.stringify(chunks))

console.log('bounds', bounds, 'chunks', chunks)

setTimeout(() => {
  for (const chunk of chunks) {
    box1
      .export('jpg', {
        blob: true,
        clip: chunk,
        relative: 'local',
        // trim:true,
        // pixelRatio: scale,
      })
      .then((ret) => {
        if (ret.data) {
          fetch(URL.createObjectURL(ret.data))

          const img = new LeaferImage({
            url: URL.createObjectURL(ret.data),
            width: w,
            height: h,
          })

          flowBox1.add(img)

          const imgSource = new Image()
          imgSource.src = URL.createObjectURL(ret.data)
          imgSource.onload = () => {
            context.drawImage(imgSource, chunk.x, chunk.y)
          }
        }
      })
  }
}, 1000)

}) }

mozbia avatar Oct 01 '25 03:10 mozbia

收到👍,我修复一下看

leaferjs avatar Oct 09 '25 01:10 leaferjs

补充一下,用 ps 看 clip 的块,白线并不是出现在 clip 的边界,而是在边界里面 大概 10 个像素左右的地方。🤣 Image

mozbia avatar Nov 23 '25 16:11 mozbia

啊。。。,收到,之前我发现clip阴影的偏移有类似这个问题,我后面看看集中一个时间解决一下

leaferjs avatar Nov 24 '25 01:11 leaferjs