Retinaの包括的なサイト準備

記事と、Retinaディスプレイをサポートするために私のサイトのいくつかを適応させる緊急の必要性によって、私はこの資料を書くよう促されました。 適応とは、サイトでの高解像度画像の準備を意味します。



おそらく、今日適応する最良の方法は、CSSのc-background-imageメソッドです。 ただし、タグ内の通常の画像に適用することは困難です。 したがって、結果を全体として達成し、解決策を探し続けるために必要な対策のリストを自分で決定することにしました。 以下に2つの方法を説明します。それぞれがそのタスクに適用できます。 示されているソリューションは、発見されたふりをするのではなく、Web開発ワークショップで私の同僚によって以前に説明された既存のメソッドの集合体であり、小規模な独自の追加です。



半分の対策または簡単な解決策

Apacheソリューション

nginxのソリューション



半分の測定:背景画像ハンドラー



コンテンツ画像の処理に煩わされたくない場合、または原則としてそれらの画像がない場合は、以下のコードに示す方法を使用し、記事をこれ以上読みません。 たとえば、あるサイトでは、画像を処理することは重要ではありませんが、インターフェース要素(アイコン)はあまりにも印象的です。 したがって、シンプルだが効果的な方法を使用できます。



.elem { background-image: url(elem.png); } @media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi) { .icon { background-image: url(elem@2x.png); } }
      
      





もちろん、elemクラスは例として提供されており、このcssをニーズに適合させる必要があります。 さて、サイトデザインのスライス画像の追加セットの準備を忘れないでください。 もちろん、特にサイトのデザインが画像で飽和している場合は、ここで動作する必要がありますが、私は、特にさまざまな「クランチ」と比較した場合、そのような動作の1回限りのパフォーマンスを支持しています。



Retina統合サポートの問題に関する声明



私は、Retinaサポートへのサイトの複雑な翻訳の問題を解決するために、次の基準を決定しました。

  1. この方法は普遍的であり、例外なくサイト上のすべての画像の処理を含む必要があります。
  2. メソッドは、リダイレクトの結果としてページの更新につながるべきではありません。
  3. メソッドは可能な限りユーザーに忠実である必要があり、Retina用に準備された元の画像をユーザーのブラウザーにアップロードしないでください。


ソリューションを説明する前に、すべての場合において、Retinaディスプレイ用に交換する必要があるすべての画像のコピーがサーバーにあると想定していることに注意してください。



サイトの設計に加えて、サーバー上でコンテンツイメージの2番目のセットを作成するタスクは私にとって緊急でした。 私の場合、ユーザーはサイトに画像をアップロードするため、サーバースクリプトを使用してメイン画像とその高解像度コピーを準備する必要がありました。



プロジェクトの個々の機能を考慮しているため、グラフィックファイルの読み込みと処理のメカニズムについては説明しませんが、ポイントは、ユーザーがアップロードした画像から、ダウンロードした画像の品質に応じてRetina用に最適化されたサイトとそのコピーの作業画像を作成する必要があることですそれが可能です。 たとえば、このプロジェクトでは、コンテンツ画像の最大幅は800pxです。 もちろん、ユーザーが幅400ピクセルの画像をアップロードすると、幅400ピクセルのコピーのみが作成されます。 しかし、ユーザーが少なくとも1600pxの幅の画像をアップロードすると、これが頻繁に発生するため、Retinaで訪問者を満足させることができます。



以前にダウンロードした画像を高解像度で保存することは不可能であり、ユーザーの知らないうちに高さと幅の値を減らすことはどういうわけか間違っていることに留意してください。 したがって、この方法には、既存の@ 2x画像を使用する場合と使用しない場合が含まれます。



Apacheソリューション



このソリューションは理想とはほど遠いものであり、サーバーリソースには高すぎるため、使用することはお勧めしません。 しかし、残念ながら、nginxが見つからない場合や設定にアクセスできない場合は、代替手段が必要であり、以下で説明します。



最初のステップは、シンプルなjsスクリプトをページテンプレート(まあ、または接続されているjsファイルの1つ)に追加することですページコンテンツおよび置換する必要のある画像を含むCSSを読み込む前にこのコードを実行することが重要です ):



 <script>document.cookie='resolution='+Math.max(screen.width,screen.height)+("devicePixelRatio" in window ? ","+devicePixelRatio : ",1")+'; path=/';</script>
      
      





JSコードはCookieを形成します。これにより、サーバースクリプトは、ユーザーがどのディスプレイを使用してサイトにアクセスしたかを把握できます。 説明されている多くのメソッドの次のステップは、jsおよびCMSスクリプトを介したリダイレクトで、Cookieの解決を分析し、正しいバージョンのグラフィックを生成します。 しかし、簡単な方法を探しているわけではなく、リダイレクトを適用していません。 .htaccessまたはapache configを使用して、CMSサイトスクリプトの外部にCookieハンドラーをインストールします。



 RewriteCond %{REQUEST_URI} ^/images #RewriteCond %{REQUEST_URI} !^/images/excluded RewriteCond %{HTTP_COOKIE} resolution=([^;,]+),2 RewriteCond %{REQUEST_URI} !@2x\.(jpe?g|gif|png)$ RewriteRule ([^.]+)\.(jpe?g|gif|png)$ $1@2x.$2 [L]
      
      





RewriteCondの最初の行は、処理されたイメージファイルが配置されているフォルダーをスクリプトに指示します。

2番目の(コメント化された)行では、例外フォルダーをハンドラーに追加できます。

RewriteCondの3行目では、ページがロードされたときに設定されたCookieを識別する、まったく同じリダイレクトを取り除きます。

4番目の条件は、既に指定された高解像度画像の処理から除外します(ファイル名の最後に「@ 2x」フラグメントがあります)。

5行目では、置換を適用する画像の形式を決定します。



説明した方法の利点:



短所:



私は、存在しない画像の問題を回避するために、考慮された方法で修正を行いました。



.htaccess行

 RewriteRule ([^.]+)\.(jpe?g|gif|png)$ $1@2x.$2 [L]
      
      





に置き換えられました

 RewriteRule ([^.]+)\.(jpe?g|gif|png)$ retina.php?img=$1@2x.$2
      
      





単純なphpスクリプトは、サーバー上の要求されたイメージの存在を判断し、それを発行します。 画像ファイルが見つからない場合、スクリプトは通常の(高解像度ではない)画像を提供します。 もちろん、要求されたデータをチェックすることで:



 <?php if (!empty($_GET['img']) && mb_substr_count($_GET['img'], '@2x')) { function isImg ($dress) { if (function_exists('exif_imagetype')) $type_file = exif_imagetype ($dress); else { $type_file = getimagesize ($dress); $type_file = $type_file[2]; } //     // 1 = GIF, 2 = JPG, 3 = PNG if (in_array($type_file, array(1,2,3))) { if (type_file==1) header("Content-Type: image/gif"); elseif ($type_file==2) header("Content-Type: image/jpeg"); else header("Content-Type: image/x-png"); header(sprintf('Content-Length: %d', filesize($dress))); return true; } unset ($type_file); return false; } $_GET['img'] = $_SERVER['DOCUMENT_ROOT'].'/'.$_GET['img']; if (file_exists($_GET['img']) && isImg ($_GET['img'])) die (file_get_contents($_GET['img'])); else { $_GET['img'] = str_replace("@2x", "", $_GET['img']); if (file_exists($_GET['img']) && isImg ($_GET['img'])) die (file_get_contents($_GET['img'])); //     readfile(), ..    .   : http://habrahabr.ru/post/151795/ } header("HTTP/1.1 404 Not Found"); //    } else header("HTTP/1.1 403 Forbidden"); ?>
      
      





もちろん、この変更によりサーバーの負荷が増加しましたが、別の解決策は見当たりませんでした。



nginxのソリューション



docomoprogitのプロンプトのおかげで、私の意見では、よりエレガントで正確な問題の解決策のバージョンが登場しました。 サーバーにnginxがあり、その構成にアクセスできる場合、phpスクリプトが与える不当に高い負荷を取り除き、Apache自体に対して簡単な調整を行うことができます。



この方法の説明の時点で、サイトテンプレートのjsをわずかに変更しました。



新しいjs:

 <script>if ("devicePixelRatio" in window && window.devicePixelRatio > 1) document.cookie='hires=1; path=/';</script>
      
      





したがって、「高解像度」画像のセットを作成する必要がある場合にのみ、Cookieの雇用が設定されます。



上記の方法の猶予は保持されます(スクリプトコードを変更することなく、どのサイトでも、バックグラウンドcssとタグの両方で置換を実行できます)。 ただし、phpスクリプトメソッドの欠点は、nginxの設定をバイパスすることです。



 if ($http_cookie ~ "hires" ) { set $hires 1; } location ~* ^(.+)@2x.(jpg|jpeg|gif|png)$ { try_files $uri $1.$2 =404; } location ~* ^.+.(jpg|jpeg|gif|png)$ { if ($hires = 1) { rewrite ^(.+).(jpg|jpeg|gif|png)$ $1@2x.$2; } }
      
      





したがって、nginxは、静的に関するすべての作業を処理します。



そして、はい、重要な明確化のためにprogitに感謝します。このアプローチでは、サイト上のすべての写真の幅と高さを指定することが必須です。 through属性またはcss-propertiesの場合、および背景画像の場合、background-size:width heightを指定する必要があります。



この問題を解決する方法は、Sam Sehnertメソッドによる網膜アートワーク自動提供に基づいています。



UP :すべてのHabrausersに感謝します。コメントで修正しました。



All Articles