Hình ảnh Retina tự động cho các trang web


104

Với Apple MacBook Pro mới với màn hình retina, nếu bạn cung cấp hình ảnh "chuẩn" trên trang web của mình, nó sẽ hơi mờ. Vì vậy, bạn phải cung cấp hình ảnh võng mạc.

Có cách nào để tự động chuyển sang @2xhình ảnh, như iOS (với Objective-C) không? Những gì tôi đã tìm thấy là: CSS cho hình ảnh có độ phân giải cao trên thiết bị di động và màn hình retina , nhưng tôi ước mình có thể tìm thấy một quy trình tự động cho tất cả các hình ảnh của mình mà không cần CSS hoặc JavaScript .

Nó có khả thi không?

CẬP NHẬT
Tôi muốn nhấn mạnh bài viết thú vị này do @Paul D. Waite đề xuất và một cuộc thảo luận thú vị về nó được liên kết bởi Sebastian .



3
Bạn có thể làm điều đó ở phía máy chủ với PHP: retina-images.complexcompulsions.com
ReLeaf

2
@ michaelward82: đối với hình ảnh nhiếp ảnh, Daan Jobsis gợi ý rằng bạn có thể cung cấp hình ảnh có kích thước võng mạc cho mọi người mà không cần kích thước tệp của bạn lớn hơn bất kỳ hình ảnh không có võng mạc nào , bằng cách tăng lượng nén JPG được áp dụng cho hình ảnh. Thực tế là hình ảnh được hiển thị thu nhỏ hoặc trên màn hình võng mạc thường có nghĩa là các tạo tác nén không hiển thị.
Paul D. Waite

1
Thực ra nó không sai , nhưng tôi đang tự hỏi nếu có một số thủ thuật để sử dụng. Trong iOS, nó tự động ... đó là lý do tại sao tôi hỏi nó! :)
jan267

2
Lưu ý rằng tác giả của "bài báo thú vị được gợi ý" đã mắc một số sai lầm lớn được mô tả ở đây: silev.org/test/Retina-resize.html - vì vậy bài viết phải được muối bỏ bể.
Sebastian

Câu trả lời:


147

Có một thuộc tính mới cho thẻ img cho phép bạn thêm thuộc tính src retina, cụ thể là srcset. Không cần javascript hoặc CSS, không cần tải hai lần hình ảnh.

<img src="low-res.jpg" srcset="high-res.jpg 2x">

Hỗ trợ trình duyệt: http://caniuse.com/#search=srcset

Các nguồn lực khác:


<img src = "LaunchAirportIcon.png" srcset = "LaunchAirportIcon@2x.png 2x">
malhal

7
Đây không chỉ là webkit nữa, Edge & Firefox cũng hỗ trợ nó. caniuse.com/#search=srcset - hiện có ~ 64% người dùng trên toàn cầu. Sau đó, hãy tính đến việc rất ít người dùng có DPI cao trên các trình duyệt không được hỗ trợ (IE và Android cũ) và cuối cùng là nó không an toàn - người dùng không có hỗ trợ chỉ cần nhìn thấy hình ảnh DPI bình thường. Chắc chắn nghĩ rằng nó đã sẵn sàng để sử dụng.
andrewb

1
Ngoài ra, không có tải kép là một lợi ích lớn. Điều này có nghĩa là bạn không bao giờ lãng phí băng thông của bất kỳ ai.
andrewb

IE một lần nữa bị hụt. Nhưng bất chấp điều này, tôi đồng ý với @andrewb. Để xây dựng dựa trên nhận xét của anh ấy, tôi đang cung cấp x2 bên trong srcđể IE / Opera sẽ luôn yêu cầu phiên bản DPI cao hơn.
Ricky Boyce,

1
Đây phải là câu trả lời được chấp nhận. Đó là giải pháp dễ dàng nhất cho chủ đề này.
Julien Le Coupanec

14

Có các giải pháp khác nhau, mỗi giải pháp có ưu và nhược điểm riêng. Cái nào tốt nhất cho bạn phụ thuộc vào nhiều yếu tố khác nhau, chẳng hạn như cách trang web của bạn được thiết kế, loại công nghệ mà khách truy cập thông thường của bạn đang sử dụng, v.v. Lưu ý rằng màn hình retina không giới hạn ở Macbook Pro Retina và iMac sắp tới, mà còn bao gồm thiết bị di động, có thể có nhu cầu riêng.

Vấn đề cũng liên quan mật thiết đến hình ảnh trong các thiết kế đáp ứng nói chung. Trên thực tế, có lẽ tốt nhất là sử dụng các kỹ thuật thiết kế đáp ứng chung, thay vì thiết kế cho các thiết bị cụ thể. Sau tất cả, công nghệ sẽ luôn thay đổi trong tương lai.

Một số giải pháp / thảo luận mà tôi đã lưu ý:

  • Vectơ nếu có thể bao gồm các kỹ thuật CSS (độ dốc, góc tròn, v.v.), SVG và phông chữ biểu tượng.
  • Cung cấp hình ảnh có độ phân giải cao ("võng mạc"), nhưng nén chúng nhiều hơn (chất lượng JPEG), theo đề xuất của Yoav Weiss hoặc để mạng di động nén chúng khi thực sự cần thiết (tức là khi di động), theo đề xuất của Paul Boag .
  • Hình ảnh thích ứng , một (chủ yếu) giải pháp phía máy chủ. Nó dựa trên một cookie lưu trữ độ phân giải màn hình, một máy chủ web được định cấu hình để phân phát hình ảnh từ tập lệnh PHP và tập lệnh được đặt tên để đọc cookie và phân phát hình ảnh thích hợp.
  • Một loạt các khả năng được mô tả và thảo luận trên Tạp chí Smashing .
  • Chỉ cung cấp độ phân giải cao hơn một chút để khắc họa võng mạc mượt mà một chút, như được đề xuất trong video của Paul Boag .
  • Kỹ thuật @ 1.5x trên A List Apart về cơ bản là cùng một ý tưởng.
  • Trong tương lai gần, <picture>thẻ có thể trở thành một giải pháp được hỗ trợ bởi nhóm làm việc W3C và thậm chí cả Apple.
  • Một kỹ thuật JavaScript do Jake Archebald đề xuất .
  • Một cuộc thảo luận sâu rộng về các kỹ thuật khác nhau trên Tạp chí Smashing và vấn đề nói chung.

Như các câu trả lời khác cho thấy, thậm chí còn có nhiều kỹ thuật hơn - nhưng có lẽ vẫn chưa có phương pháp thực hành tốt nhất.

Một điều tôi thắc mắc là làm thế nào để kiểm tra và gỡ lỗi một số kỹ thuật này mà không cần có sẵn (các) thiết bị tương ứng ...


11

Vì chưa có ai đề cập đến điều hiển nhiên nên tôi sẽ đưa nó ra khỏi đó: nếu có thể, chỉ cần sử dụng SVG. Chúng xuất hiện ở độ phân giải võng mạc đẹp mà không cần nỗ lực gì.

Hỗ trợ cho nó là tốt với IE8 là con khủng long chính đáng lo ngại. Kích thước tệp được nén thường tốt hơn định dạng bitmapped (png / jpg) và hình ảnh linh hoạt hơn; bạn có thể sử dụng lại chúng ở các độ phân giải khác nhau và thiết kế lại nếu cần, giúp tiết kiệm cả thời gian phát triển và băng thông tải xuống.


Tôi thích gợi ý của bạn! Vấn đề duy nhất svglà với các trình duyệt cũ hơn.
267

15
Và trường hợp bạn có ảnh
Baumr

Thật vậy, chúng tuyệt vời với điều kiện bạn có phiên bản Vector của hình ảnh bạn muốn sử dụng, nhưng tôi không tin rằng bạn có thể lưu hình ảnh raster bình thường dưới dạng SVG.
Chuck Lê Butt

Không có cách nào "tốt" để chuyển đổi theo hướng đó, do đó là "nếu có thể". Nhưng ngoại trừ các trang web nhiếp ảnh, v.v., bạn thường sẽ tạo tài sản nghệ thuật của mình, vì vậy tôi khuyên bạn nên thực hiện chúng dưới dạng vectơ, có thể dễ dàng chuyển đổi thành raster nếu bạn muốn, ở bất kỳ độ phân giải nào.
svachalek

SVG không hoạt động cho ảnh chụp màn hình (ví dụ: khi ghi lại các tính năng của giao diện người dùng).
Greg Brown

9

Đây là ít mixin mà tôi sử dụng để đạt được điều này cho ảnh nền. retina.js không hoạt động cho hình nền nếu bạn đang sử dụng dotLess, vì nó yêu cầu kết hợp riêng của nó, bản thân nó sử dụng đánh giá tập lệnh không được hỗ trợ trong dotLess.

Mẹo với tất cả những điều này là nhận hỗ trợ của IE8. Nó không thể dễ dàng thực hiện kích thước nền nên trường hợp cơ sở (truy vấn không phải phương tiện di động) phải là một biểu tượng đơn giản, không có tỷ lệ. Sau đó, truy vấn phương tiện sẽ xử lý trường hợp võng mạc và có thể sử dụng miễn phí lớp kích thước nền vì võng mạc sẽ không bao giờ được sử dụng trên IE8.

.retina-background-image( @path, @filename,@extension, @size )
{
     .background-size( cover );
     background-image: url( "@{path}@{filename}@{extension}" );
         @media only screen and ( -webkit-min-device-pixel-ratio: 2 ),
                only screen and ( -moz-min-device-pixel-ratio: 2 ),
                only screen and ( -o-min-device-pixel-ratio: 2/1 ),
                only screen and ( min-device-pixel-ratio: 2 )
         {
             background-image:url( "@{path}@{filename}@x2@{extension}" );
             background-size:@size @size;
         }
}

Mẫu sử dụng:

.retina-background-image( "../references/Images/", "start_grey-97_12", ".png", 12px );

Ths yêu cầu bạn có hai tệp:

  • start_grey-97_12.png
  • start_grey-97_12@2x.png

Nơi 2xtệp có độ phân giải gấp đôi cho võng mạc.


8

Chỉ cần cung cấp hình ảnh võng mạc cho mọi người và ép hình ảnh xuống một nửa kích thước gốc bên trong phần tử hình ảnh. Giống như giả sử hình ảnh của bạn 400pxrộng và cao - chỉ cần chỉ định chiều rộng hình ảnh 200pxđể làm cho hình ảnh trông sắc nét như sau:

<img src="img.jpg" width="200px" height="200px" />

Nếu hình ảnh của bạn là ảnh, bạn có thể tăng độ nén JPG trên nó mà không làm cho nó trông xấu đi, vì các thành phần nén JPG có thể sẽ không hiển thị khi hình ảnh được hiển thị tại 2x: xem http://blog.netvlies.nl/ design-interactie / retina-Revolution /


1
Daan Jobsis gợi ý rằng cho hình ảnh chụp ảnh, điều này thậm chí không phải dẫn đến kích thước file lớn hơn: xem blog.netvlies.nl/design-interactie/retina-revolution
Paul D. Waite

Tốt nhất bạn nên chỉ định chiều cao để trình duyệt có thể sắp xếp trang trước khi hình ảnh được tải xuống.
Paul D. Waite

8
Tôi không nghĩ đó là một ý tưởng tuyệt vời cung cấp một tập tin hình ảnh lớn hơn và nặng hơn nếu không cần thiết ...
jan267

1
@ PaulD.Waite thú vị cho điều đầu tiên và chính xác cho điều cuối cùng! :)
jan267 6/12/12

2
@ PaulD.Waite Lưu ý rằng tác giả của bài viết được liên kết đã mắc một số sai lầm lớn được thảo luận ở đây: silev.org/test/Retina-resize.html - vì vậy bài viết phải được muối bỏ bể. Đặc biệt là "hình ảnh không được chia tỷ lệ ở bên phải" trên thực tế được chia tỷ lệ và do đó không thể thực sự so sánh với hình ảnh có độ phân giải được tăng gấp đôi chính xác (yêu cầu trình duyệt của bạn hiển thị đúng hình ảnh trong cửa sổ mới và bạn sẽ thấy những gì tôi và tác giả của bài báo khác đó có nghĩa là)
Sebastian

1

nếu hình nền của nó, một cách đơn giản để làm điều này là:

    #image { background: url(image.png); }

@media only screen and (-webkit-min-device-pixel-ratio: 2),
       only screen and (-moz-min-device-pixel-ratio: 2),
       only screen and (-o-min-device-pixel-ratio: 2/1),
       only screen and (min-device-pixel-ratio: 2) {
           #image { background: url(image@2x.png); background-size: 50%; }
}

một cách đơn giản khác là sử dụng phương pháp này:

Chỉ cần thay thế:

<img src="image.jpg" alt="" width="200" height="100" />

với

<img src="image@2x.jpg" alt="" width="200" height="100" />

1

Tôi đã tìm thấy cách thú vị này để cung cấp hình ảnh nhiều độ phân giải.
Nó thực sự sử dụng CSS, thứ mà tôi muốn tránh và chỉ hoạt động trong Safari và Chrome.
Tôi đang nói về image-set.

Đây là một ví dụ do Apple cung cấp ( tại đây ):

header {
    background: -webkit-image-set( url(images/header.jpg)    1x,
                                   url(images/header_2x.jpg) 2x);
    height: 150px; /* height in CSS pixels */
    width: 800px; /* width in CSS pixels */
}

Tôi cũng muốn chia sẻ hai liên kết này:


1

Với JSF, bạn có thể tạo thẻ Khuôn mặt tùy chỉnh để đỡ phải thêm srcsetvào mỗi hình ảnh.

Trong bạn, taglib.xmlbạn có thể có một cái gì đó như:

<tag>
  <tag-name>img</tag-name>
  <source>tags/img.xhtml</source>
  <attribute>
    <name>src2x</name>
    <required>true</required>
    <type>java.lang.String</type>
  </attribute>
</tag>

Và thẻ của bạn có thể trông giống như sau:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
                xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

  <img src="#{fn:replace(src2x, '@2x', '')}"
       srcset="#{src2x} 2x"/>

</ui:composition>

Có thể được sử dụng như:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:myTag="http://your.com/namespace-of-taglib">
  <myTag:src2x="image@2x.jpg"/>
</html>

Và sẽ hiển thị:

<img src="image.jpg"
     srcset="image@2x.jpg 2x"/>

0

Vấn đề này đặc biệt phức tạp với các trang web đáp ứng nơi và hình ảnh có thể có chiều rộng khác nhau tùy thuộc vào kích thước trình duyệt. Ngoài ra, khi xử lý một CMS trong đó nhiều người chỉnh sửa có khả năng tải lên hàng nghìn hình ảnh đối với tôi, tôi thấy có vẻ không thực tế khi yêu cầu mọi người tải lên các hình ảnh được nén đặc biệt.

Vì vậy, tôi đã viết một tập lệnh có tính đến điều này, nó kích hoạt ở cuối trang và khi kết thúc thay đổi kích thước. Mỗi lần tính đến mật độ điểm ảnh và kích thước hình ảnh đang chiếm giữ.

http://caracaldigital.com/retina-handling-code/


0

Nếu bạn không nản lòng vì sợ sử dụng java-script thì đây là một bài viết hay http://www.highrobotics.com/articles/web/ready-for-retina.aspx . Nó có giải pháp rất đơn giản.

ví dụ trong JSFiddle đáng giá một nghìn từ.

Sử dụng:

<img onload="getImgSrc(this,'image_x1.png')" width="100" height="100" />

JS:

/* RETINA READY IMG SRC */
function getImgSrc(img, src) {
    var srcResult = src;
    // if high-res screen then change _x1 on _x2
    if (window.devicePixelRatio > 1 && 
        src.indexOf("_x1.")>=0) {
          srcResult = src.replace("_x1.", "_x2.");
    }
    img.onload = null; //protect from second rasing
    img.src = srcResult;    
}

$(document).ready(function(){
  // fire onload trigger on IMG tags that have empty SRC attribute
  var images = $('img:not([src=""])');
    images.each(function(i) {
        $(this).trigger('onload');            
    });
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.