2016-08-03 20 views
12

Tôi đang thu nhỏ nội dung của trình chỉnh sửa biểu đồ tuyệt vời của tôi bằng cách sử dụng transform: scale(x). Khi thu nhỏ tỷ lệ đi xuống theo hướng 0 (độc quyền), khi phóng to tỷ lệ tăng lên, tối đa là 1 (bao gồm) có nghĩa là thu phóng toàn bộ hoặc tỷ lệ ban đầu.Cải thiện chất lượng hình ảnh của các phần tử được rút gọn CSS

Tuy nhiên, khi thu nhỏ đáng kể, chất lượng hình ảnh bắt đầu trở thành thực sự ồn ào - vui lòng xem xét ví dụ sau đây, và nhận thấy cách thu nhỏ sẽ xuất hiện hình ảnh ồn ào:

var graphContainer = document.getElementById("graph-container"); 
 
var zoomInButton = document.getElementById("zoom-in-button"); 
 
var zoomOutButton = document.getElementById("zoom-out-button"); 
 
var zoomLevel = 1; 
 

 
zoomInButton.addEventListener("click", function() { 
 
    zoomLevel = Math.max(1, zoomLevel - 0.25); 
 
    graphContainer.style.transform = "scale(" + (1/zoomLevel) + ")"; 
 
}); 
 

 
zoomOutButton.addEventListener("click", function() { 
 
    zoomLevel = zoomLevel + 0.25; 
 
    graphContainer.style.transform = "scale(" + (1/zoomLevel) + ")"; 
 
});
#editor-container { 
 
    background-color: #001723; 
 
} 
 

 
#graph-container { transform-origin: top center; }
<div id="editor-container"> 
 
    <button id="zoom-in-button">Zoom in</button> 
 
    <button id="zoom-out-button">Zoom out</button> 
 
    <div id="graph-container"> 
 
     <img class="shape" src="http://i.imgur.com/zsWkcGz.png" /> 
 
    </div> 
 
</div>

Demo also on JSFiddle

Hình ảnh này là hình vẽ được vẽ tương tác alizes một kết nối giữa hai nút đồ thị, xuất khẩu thành png.


Hãy thu nhỏ và xem cách ồn ào dòng có nghĩa là, mặc dù zoom được thực hiện trong bước 0.25 và với CSS. Làm cách nào để loại bỏ nhiễu pixel này? Sự cố xảy ra ở cả Google Chrome và Microsoft Edge mới nhất, chưa được kiểm tra trong các trình duyệt khác. Vấn đề xảy ra có và không có tăng tốc 3D GPU.

Lưu ý: rõ ràng, đây là một Minimal, Complete, and Verifiable example và công việc thực tế rất phức tạp độ lớn hơn.

Hundrends hình dạng dòng được rút procedurally lên một canvas (< 1ms trên mỗi dòng) và sau đó lưu trữ để img yếu tố đồng bộ bằng toDataUrl (~ 40ms trên mỗi dòng) khi nhàn rỗi, do đó màn hình panning - đó cũng là một tính năng cần thiết - hoạt động trơn tru hơn, khi di chuyển phần tử img trên màn hình rẻ hơn nhiều so với việc di chuyển phần tử canvas (hoặc vẽ lại tất cả các dòng trên một canvas), cho dù đó là phần tử, vùng chứa hoặc khung nhìn trình duyệt được dịch sang một hướng nhất định.

Như vậy, mipmaps tạo ra là không thực sự là một lựa chọn, hoặc chỉ như là một phương sách cuối cùng, vì nó sẽ đi kèm với một đáng kể phạt hiệu suất (mỗi mip cấp sẽ phải được lưu trữ vào một hình ảnh riêng biệt, hiệu suất cắt giảm một nửa ở mức tối thiểu). Tôi muốn tin rằng nó có thể tránh được, mặc dù. Việc vẽ lại các hình dạng đường kẻ trên mỗi bước thu phóng sẽ làm giảm hiệu suất của công việc xuống một trình chiếu.

Sau đây là danh sách những điều tôi đã cố gắng, không có tác dụng:

  • Hinting với chất lượng hình ảnh tốt hơn bằng cách xác định giá trị tài sản CSS sau, trên các yếu tố hình dạng riêng của mình, hoặc các container:
image-rendering: pixelated | optimizeSpeed | optimizeQuality 
  • Buộc nâng cao lớp vẽ vào khả năng tăng tốc GPU với một hình nộm transform
  • Sử dụng scale3d thay vì scale
  • giảm một nửa img.widthimg.height và sau đó bù đắp bằng cách tăng gấp đôi img.style.widthimg.style.height
  • Không bộ nhớ đệm kết quả vải vào img và thay vào đó hiển thị các yếu tố canvas trực tiếp (hiệu suất chậm hơn, cùng chất lượng xấu)

Tôi cũng đã thử sử dụng filter: blur khi thu nhỏ, nhưng nó did not yield a better quality, vì hiệu ứng làm mờ chính nó được áp dụng sau hình dạng đã cho đã được hiển thị trên màn hình.

Tôi còn có thể làm gì khác để loại bỏ nhiễu điểm ảnh này, ngoài việc tạo các phiên bản được rút gọn của từng hình dạng, tạo một hệ thống mipmap (LOD) phần mềm? (trong đó, như tôi đã viết, muốn mạnh tránh)


thế nào là câu hỏi này khác với các mảng similar questions tra chất lượng hình ảnh xấu từ downscaling?

  • Đây là vùng chứa được hạ cấp (và với CSS chuyển đổi), thay vì các yếu tố hình ảnh riêng lẻ. Không có thao tác được thực hiện cho dữ liệu hình ảnh thực tế, đó là những gì được thảo luận trong các chủ đề tương tự.
+0

Tôi nghĩ hình ảnh "PNG" cũng là hình ảnh raster hơn vì sao chất lượng hình ảnh không phù hợp khi thu phóng. Bạn đã thử điều này với hình ảnh định dạng vector chưa. ? –

+0

sử dụng đồ họa vector có thể mở rộng thay vì hình ảnh raster hoặc u có thể vẽ nó trên canvas. – Smile0ff

+0

@ Smile0ff Tôi đang vẽ những hình dạng này thành canvas (hãy xem lưu ý, hàng trăm ảnh), và chỉ sau đó là kết quả canvas được lưu vào phần tử 'img' - nếu không, nội dung di chuyển trên màn hình thực sự xấu. Việc vẽ lại trên mỗi lần thu phóng sẽ ngay lập tức xóa hiệu suất xuống trình chiếu. –

Trả lời

2

Bạn có thể nhận được kết quả tốt hơn nhiều bằng cách sử dụng hình ảnh SVG thay vì PNG và chúng cũng rất dễ tạo và nhúng trong mã của bạn, thậm chí bạn không cần lưu trữ chúng.

Như bạn có thể thấy trong số demo SVG này sẽ không pixelate hoặc bị mờ và bạn sẽ nhận được kết quả tốt hơn nữa ở màn hình có độ phân giải cao như màn hình Retina.

Mã SVG:

<svg class="shape" width="440px" height="319px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 
     <path d="M1,316.040132 C1,316.040132 241.5837,339.680482 241.5837,163.497447 C241.5837,-12.6855883 439,2.31775322 439,2.31775322" id="Path" stroke="#50E3C2" stroke-width="2"></path> 
    </g> 
</svg> 

Rõ ràng là không hoàn hảo.

2

Nội suy của hình ảnh với cạnh sắc nhọn chắc chắn sẽ tạo hiện vật. Ngay cả khi nó được antialised, ngay cả khi nó là blured. Bạn có thể kiểm tra điều này trong Photoshop, bạn sẽ nhận được kết quả tương tự.

Ngay cả cách tiếp cận mipmap cũng không hoạt động.

Vấn đề cố hữu là pixel không thể giữ lại tất cả thông tin về các hình dạng vector phức tạp của bạn; và khi bạn bóp pixel, hình dạng bị mất.Có hai giải pháp để nâng cao chất lượng:

  • hoặc làm cho hình ảnh với độ phân giải cao hơn trước khi nhân rộng nó để có nhiều pixel để lưu trữ các mục đích của hình dạng của bạn
  • hoặc thẳng làm cho hình dạng vector của bạn ở quy mô bạn đang nhắm đến
+0

Có vẻ như tôi sẽ cần thực hiện một cách tiếp cận khác và cắt một số tính năng tương tác. BTW, với cách tiếp cận mipmap, tôi tăng kích thước 'scale' của hình dạng thực tế theo tỷ lệ, do đó không bao giờ thực sự thu nhỏ hình dạng bên dưới' 0,5' kích thước ban đầu của nó. Trực quan nó tạo ra một hình ảnh chất lượng rất cao, nhưng nó là rất hiệu suất đòi hỏi vì tất cả các recaching mà phải được thực hiện. –

Các vấn đề liên quan