2011-07-06 46 views
3

我一直在開發一個phonegap項目,試圖構建Android和iOS。主要想法是訪問手機庫中保存的圖片,將該圖片保存到HTML img元素,然後將該img元素繪製到畫布上。從那裏,用戶可以縮放和旋轉圖像。iOS平臺上的HTML5畫布縮放問題

我在Android上沒有問題。我已經使用仿真器和設備進行了測試,並測試了各種設備(不同的像素比率,密度等),並且生成的畫布轉換始終可以提供預期的結果。

另一方面,iOS版本並沒有那麼成功。縮放/旋轉畫布看起來很好,直到我縮放比原始大小稍大的畫布(大約比原始大4-5個像素)。將畫布縮小後,畫布上繪製的圖像會發生變化。現在不用看現在的整個圖像,我通常會在整個畫布上畫出一小部分圖像(通常是左上角)。

我的畫布,以html:

<canvas id="sourceImgCanvas" width="200" height="200" style="z-index:1; position:absolute; left:5%; top:100px;"></canvas> 

我從手機文庫接收的圖像幾乎總是在手機屏幕過大。我縮小圖像並記錄縮小圖像的比率(如果沒有縮放發生,繪製比例爲1,如果圖像縮小以適應屏幕,則比例大於1)。 PhoneGap的句柄抓住從手機庫中的圖片,我簡單地使用imageURI從照片回來,將其設置爲一個img元素Phonegap Camera API

// Called when a photo is successfully retrieved 
function onPhotoURISuccess(imageURI) 
{ 
    sourceImage = document.getElementById('sourceImg'); 
    sourceImage.src = imageURI; 

    //signal that user can manipulate photo with touch inputs 
    b_editPhotoAllowed = true; 
} 

要縮放的畫布,我對右下角的箭頭畫布的一角。拖動時,它會記錄距離畫布左上角多遠,並根據距離設置畫布高度/寬度。

//Calls when user is dragging the arrow resize button. Updates the source image size 
function ResizeSourceImage() { 
    var horizontalDistanceFromTopLeft = parseFloat(ovalCanvas.style.left) + ovalCanvas.width - endX; 
    var verticalDistanceFromTopLeft = parseFloat(ovalCanvas.style.top) + ovalCanvas.height - endY; 

    //update canvas size with new length 
    sourceImgCanvas.width = originalSrcImgWidth - horizontalDistanceFromTopLeft; 
    sourceImgCanvas.height = originalSrcImgHeight - verticalDistanceFromTopLeft; 

    //re-draw based on new size 
    sourceImgContext.drawImage(sourceImg, 0, 0, pictureWidth * drawRatio * drawRatioMod, pictureHeight * drawRatio * drawRatioMod, 0, 0, sourceImgCanvas.width, sourceImgCanvas.height); 
} 

上面drawRatio是我存儲在重新調整大小的圖像的比例(代碼在這裏未示出;它比較長,但簡單。)

drawRatioMod被予置而試驗的值,並且是我的問題的主要焦點。在Android上,我設置了drawRatioMod = 1,以便繪圖不受影響。在iPhone4/iPad(我可以測試的設備)上,我設置了drawRatioMod = 0.5。這解決了我在iOS上使用html5 canvas時遇到的一些初始問題:由於iPhone4的分辨率實際上是屏幕尺寸的兩倍,因此我將源圖像的長度/寬度縮減爲一半。

上述ResizeSourceImage()函數在用戶每次移動調整大小箭頭工具時調用,因此更新了畫布大小。如果我按比例縮小,則圖像將適當地調整爲新的畫布大小只有。如果我將畫布縮放超過5-6個像素,則畫布不再繪製整個源圖像;相反,畫布只在整個畫布上繪製圖像的左上角。

我一直在解決這個問題幾天,並沒有運氣。我最初認爲它與設備像素比率有關(可通過Javascript window.devicePixelRatio訪問),但我已經在多個不同比率的Android設備上進行了測試,並且從未得到過此結果。

我覺得我很接近解決問題,因爲在iOS上擴展時圖像只顯示不正確。任何指針/提示,非常感謝!我已經嘗試了幾個與window.devicePixelRatio相關的修補程序,但是我的iPad的iPhone4模擬器總是返回1的像素比率(這看起來不正確),而且我沒有使用這種修補程序的運氣。

乾杯! (我試圖張貼關於畫布縮放和繪製的基本代碼,如果你想看到更多的代碼,我可以發佈更多的代碼;希望能找到一個與中國的長城不相似的帖子:))

回答

3

經過幾天的測試,我終於找到了罪魁禍首:使用myContext.drawImage()切片圖像只是iOS的一大痛苦(可能是由於視網膜顯示,但我不是100 %肯定)。

我做的反而是雙緩衝和使用myContext.drawImage()只有規模,而不是切片。

FelineSoft在帆布相關的幾件事情上有一個偉大的職位。所以http://www.felinesoft.com/blog/index.php/2010/09/accelerated-game-programming-with-html5-and-canvas/

,而不是切片的原始圖像,像這樣:雙緩衝這裏要解釋

sourceImgContext.drawImage(sourceImg, 0, 0, pictureWidth * drawRatio * drawRatioMod, pictureHeight * drawRatio * drawRatioMod, 0, 0, sourceImgCanvas.width, sourceImgCanvas.height); 

我,而不是繪製圖像緩衝區,然後繪製到用戶看到屏幕上的畫布。回首過去,緩衝可能沒有必要解決這個規模問題我有,但它是一個好習慣,習慣:

​​

正如你所看到的,我不再使用canvas.drawImage()切片源圖像,我只是將它縮放以適合畫布。

似乎我是以錯誤的方式去解決問題,但希望遇到類似問題的其他人會發現這種方法很有幫助。