2014-11-14 5 views
4

iPhone 5에 KineticJS 5.1.0 무대가 있습니다. iPhone의 화면 크기로 인해 무대는 320px x 320px로 제한됩니다. 캡처 한 이미지는 1280x1280 픽셀입니다. 축소로 인해 품질을 잃지 않고 무대에서이 이미지를 처리 ​​할 수 ​​있기를 원합니다. 여기 KineticJS : 화질 저하없이 화면/스테이지 크기보다 훨씬 큰 이미지를 편집하려면 어떻게합니까?

원본 이미지를입니다 (큰 버전 : https://dl.dropboxusercontent.com/u/47067729/originalImage2.jpg) :

enter image description here

이미지 : 여기

enter image description here

내가 무대에 이미지를로드 할 때 발생하는 것입니다 아주 이상하게 보입니다. 이미지에서 볼 수있는 것처럼 많은 스트립이 있습니다.

필터를 적용하면 이미지가 다음과 같이 보입니다. 그것이 어떻게 보일지하지

enter image description here

.

나는 어떻게 품질을 잃어버린없이 내 화면/스테이지 크기보다 훨씬 더 큰 이미지를 편집 할 수 있습니다이 문제

console.clear(); 


var imageObj = new Image(); 
var img = null; 
var saveBtn = document.getElementById("save"); 
var resultImage = document.getElementById("resultImage"); 
var original = document.getElementById("original"); 
var downloadLink = document.getElementById("DownloadLink"); 

Kinetic.pixelRatio = 4; 
stage = new Kinetic.Stage({ 
     container: 'container', 
     width: 320, 
     height: 320 
    }); 
layer = new Kinetic.Layer(); 

img = new Kinetic.Image({ 
    x: 0, 
    y: 0, 
    image: new Image() 
}); 

layer.add(img); 
stage.add(layer); 

imageObj.onload = function() { 

    var tmpWidth = Math.floor(imageObj.width /2); 
    var w = Math.min(tmpWidth, 320); 
    var h = imageObj.height * w/imageObj.width; 

    img.setImage(this); 
    img.setWidth(w); 
    img.setHeight(h); 

    img.cache(); // 5.1.0 

    // img.setFilter(Kinetic.Filters.Shinny); // 4.5.2. 
    img.filters([Kinetic.Filters.Shinny]); // 5.1.0 
    layer.draw(); 
}; 

imageObj.crossOrigin = "anonymous"; 
var imageUrl = "https://dl.dropboxusercontent.com/u/47067729/originalImage2.jpg"; 
imageObj.src = imageUrl;  
original.src = imageUrl; 

saveBtn.onclick = function(evt) { 
    console.log("save"); 
    var canvas = $(stage.getContent()).find('canvas').get(0); 

    console.log("canvas: "+canvas); 
    var dataURL = canvas.toDataURL('image/jpeg', 1.0); 
    resultImage.src = dataURL; 
    downloadLink.href = dataURL; 

}; 

에게 보여주는 JsFiddle (http://jsfiddle.net/confile/qhm7dn09/)을 만들어?

편집 : 사용자에게 표시되는 스테이지/캔버스는 여전히 미리보기입니다. 원본 이미지를 축소해서는 안됩니다. 효과를 적용하고 스테이지를 내보내기 한 후에는 품질 저하없이 이미지를 원래 크기와 동일한 크기로 내보내고 싶습니다. 나는 320px x 320px 스테이지를 1280px x 1280px로 크기를 조정하여 휴 품질 손실을 일으키고 싶지 않습니다.

+0

바이올린이 작동하지 않습니다. pixelRatio 설정을 줄이려고 했습니까? – K3N

답변

4

iPhone에서 나타나는 벨소리 패턴은 resizing artifacts이며, 종류는 Moiré pattern입니다. actuallyprettycommon입니다.

서면의, 우리는 캔버스가 우리의 이미지를 확장 방법에 대한 제어 할 수 없습니다, 그래서 우리는 그것을 해결해야

  1. Maunally이 scaling algorithm 더 적당한를 사용하여 하나 개 이상의 스케일 이미지를 생성합니다. 목표는 스케일링을 피하는 것이고, 따라서 어떤 인공물도 피하는 것입니다.

  2. step down algorithm을 구현하고 키네틱에 전달하기 전에보다 적합한 치수의 이미지를 생성하십시오.

  3. 다운 스케일링하기 전에 이미지를 흐리게 처리하면 아티팩트가 흐려 지지만 제거되지는 않습니다. Kinetic에서는 Blur 필터를 정상적으로 적용하기 만하면됩니다.

  4. 더 적합한 scaling algorithm을 구현하고 동적으로 이미지를 크기 (예 : 자동 # 1)로 확대/축소하는 데 사용합니다.

당연히 첫 번째 두 가지 접근 방식이 권장됩니다.


320px 스테이지는 320px 이미지 만 내 보냅니다. 크기 조정없이 원본 이미지를 원래 크기로 내보내려면 큰 스테이지에서 내보내기해야합니다. 새 단계가 표시 될 필요는 없습니다. 이것은 off-screen rendering입니다.

나는 바이올린의 그것을 입증하는 핸들러를 저장 수정 한 : http://jsfiddle.net/qhm7dn09/13/embedded/result

명심 자바 스크립트데도 빨리 또는 기본 프로그램만큼 효율적이며 없다는 것을 가장 힘든 시간 브라우저에서 큰 이미지를 처리하는 것입니다 모바일 JS 사용.


원본 질문은 축소 된 이미지 품질을 향상시키는 방법을 묻습니다.

스톡 흐림 필터가 주어지면 Kinetic 5.1에 대해 선명 필터를 구현하는 것이 상대적으로 쉽습니다. 특히, 언샵 마스크 필터.

Kinetic.Filters.UnsharpMask = function kinetic_filter_unsharpmask(imageData) { 
    var amount = this.attrs.unsharpAmout/100; // Normally 1 to 100 (%) 
    var radius = Math.round(this.attrs.unsharpRadius); 
    var threshold = Math.round(this.attrs.unsharpThreshold); // 1 to 765 
    if (amount && radius > 0 && threshold > 0) { 
     var data = imageData.data, len = data.length, i; 
     // Copy the image and call blur filter on it 
     var blurData = new Uint8Array(imageData.data.buffer.slice(0)); 
     Kinetic.Filters.Blur.call( 
      { blurRadius: function(){ return radius; } }, 
      { data: blurData, width: imageData.width, height: imageData.height }); 
     // Unsharp mask 
     for (i = 0 ; i < len ; i += 4) { 
      // Calculate difference 
      var d = [ data[i] - blurData[i], data[i+1] - blurData[i+1], data[i+2] - blurData[i+2] ]; 
      var diff = Math.abs(d[0]) + Math.abs(d[1]) + Math.abs(d[2]); 
      // Apply difference 
      if (diff && diff >= threshold) { 
       data[i ] = Math.max(0, Math.min(Math.round(data[i ] + d[0] * amount), 255)); 
       data[i+1] = Math.max(0, Math.min(Math.round(data[i+1] + d[1] * amount), 255)); 
       data[i+2] = Math.max(0, Math.min(Math.round(data[i+2] + d[2] * amount), 255)); 
      } 
     } 
    } 
} 

사용법 :

img = new Kinetic.Image({ 
    x: 0, y: 0, image: imageObj, 
    unsharpRadius: 3, // Pixel range, should be integer (blur filter will round it to integer) 
    unsharpAmout: 50, // 1 to 100 
    unsharpThreshold: 10 // 1 to 765 
}); 
img.filters([Kinetic.Filters.UnsharpMask]); 

또한 다른 라이브러리에 의해 발생 될 가능성이 렌더링 된 이미지에서 인식의 차이에 대해 질문 원래의 질문입니다. 다른 색상을 표시합니다, 다른 설정이나 모드를

  1. 다른 모니터 (심지어 같은 모델), 또는 같은 모니터 :

    는 경험에서, 이러한 요소는 일반적으로 표시되는 색상의 외관에 영향을 미칩니다.

  2. Adobe Gamma 또는 일부 디스플레이 카드 드라이버와 같은 화면 조정 소프트웨어는 색상을 상당히 왜곡시킬 수 있습니다.
  3. 다른 시야각; 동일한 이미지는 왼쪽과 오른쪽, 위아래로 다르게 보일 수 있습니다.
+0

질문이 업데이트되었습니다. 좀 봐 주시겠습니까? – confile

+0

@confile 흠. 실제로 원래 질문과는 완전히 다른 답변을 가진 새로운 질문입니다. 다행스럽게도 새로운 것은 아니므로 관련된 질문과 코드를 알려줄 답변을 업데이트했습니다. – Sheepy

+0

내 편집을 참조하십시오 : 사용자에게 제공된 무대/캔버스는 여전히 일종의 미리보기입니다. 원본 이미지를 축소해서는 안됩니다. 효과를 적용하고 스테이지를 내보내기 한 후에는 품질 저하없이 이미지를 원래 크기와 동일한 크기로 내보내고 싶습니다. 나는 320px x 320px 스테이지를 1280px x 1280px로 크기를 조정하여 휴 품질 손실을 일으키고 싶지 않습니다. – confile

관련 문제