iT邦幫忙

0

使用JS創建canvas,結果width一直為0

  • 分享至 

  • xImage

大家好,我想請問,
因為我的原始的canvas大小很大(width:2200,height:580)

我想把它縮小後,縮到width:580,height:300,然後放到pdf
我試過直接將原始的canvas縮小後導出,不過發現一個問題,就是畫質會不好。

所以我想在測試看看,做一個button,
然後在botton裡,直接重畫一個width:580,height:300的canvas,
然後再導出。
不過遇到一個問題。
就是我的ctxSmall的width跟height一直為0
在JS裡設定也一樣......

會跳出這個錯誤:

Uncaught DOMException: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The image argument is a canvas element with a width or height of 0.
    at testP (http://localhost:3000/src/components/Home/ChartBar.vue?t=1646729207576:740:13)
    at HTMLLIElement.<anonymous> (http://localhost:3000/src/components/Home/ChartBar.vue?t=1646729207576:844:42)

用log抓到canvas是這樣:

<canvas width="0" height="0" style="width: 0px; height: 0px; display: block; box-sizing: border-box;">

以下是我的程式碼:

const testButton = function(){
    let ctxSmall = document.createElement('canvas');
    ctxSmall.width = 580
    ctxSmall.height = 300
    ctxSmall.style.width = '580px'
    ctxSmall.style.height = '300px'
    
    console.log('ctxSmall',ctxSmall);//測試
    let ContextSmall = ctxSmall.getContext("2d")
    let GradientStroke = ContextSmall.createLinearGradient(0, 0, 0, 150);
    // 定義漸變的 偏移 和 顏色
    GradientStroke.addColorStop(0, "#00FFFF");
    GradientStroke.addColorStop(1, "#75d1b8");
    let MyChartSmall = new Chart(ctxSmall, {.......})
    
    let CanVas = document.createElement('canvas')
    CanVas.width = ctxSmall.width;
    CanVas.height = ctxSmall.height;
    let ConText = CanVas.getContext('2d');
    ConText.fillStyle='#1a114e';
    ConText.fillRect(0, 0, 580, 300);
    ConText.drawImage(ctxSmall, 0, 0,580,300);
    return CanVas.toDataURL('image/jpeg', 1.0);
}
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

3
淺水員
iT邦大師 6 級 ‧ 2022-03-08 18:35:30
最佳解答

我這邊不論是 Firefox, Chrome, Edge 都是 580 x 300,不會有你說的現象

另外畫質的問題
除非你是因為後端縮圖的演算法不佳,覺得瀏覽器的縮圖演算法效果比較好
否則就是單純是像素不足的問題

如果是像素不足的問題
那麼應該傳原始尺寸給後端
drawImage 的縮圖一樣是像素降低,並不是把原本的像素塞到比較小的長寬內

greenriver iT邦研究生 5 級 ‧ 2022-03-08 19:04:04 檢舉

先謝謝淺水員大大,幫了我好幾次
/images/emoticon/emoticon32.gif
那可能是我vue或chart.js配合canvas的用法錯誤..

因為我後端只傳JSON到前端(Vue),
所以我就在前端做"下載PDF"。

淺水員 iT邦大師 6 級 ‧ 2022-03-08 19:26:04 檢舉

原來是你
那接續上次這篇
之前我偷懶把「圖片原始長寬」直接設定到「pdf 中顯示的長寬」
其實這兩個是分開的

pdf.addObject({
    Type: '/XObject',
    Subtype: '/Image',
    Width: opt.width, //圖片原始寬度
    Height: opt.height, //圖片原始高度
    ColorSpace: '/DeviceRGB',
    BitsPerComponent: '8',
    Filter: '[/ASCII85Decode /DCTDecode]'
}, jpegbase85+'~>', imgId);
pdf.addObject({}, `${pdf中顯示的寬度} 0 0 ${pdf中顯示的高} ${opt.x} ${opt.y} cm /Im1 Do`, contentId);

要縮放是調整「pdf中顯示的寬度跟高度」就好,原始圖片不用縮放

greenriver iT邦研究生 5 級 ‧ 2022-03-09 09:00:19 檢舉

淺水員
謝謝!!!成功了 你真的好厲害

我JS截圖部分,跟PDF還要再練一練
/images/emoticon/emoticon52.gif

我要發表回答

立即登入回答