HTML / CSSで画像をグレースケールに変換する


619

だけでカラービットマップをグレースケールで表示する簡単な方法はありHTML/CSSますか?

IE互換である必要はありません(そうでないと思います)。FF3やSf3で動作する場合は、これで十分です。

SVGとCanvasの両方でそれを実行できることはわかっていますが、それは現在、多くの作業のようです。

本当に怠惰な人がこれを行う方法はありますか?


14
「IE互換である必要はありません(また、互換性がないと思います)」 ?? IEは1997年(IE4)から一連のDXフィルターを 提供しており、これは単なるCSSなどでこの機能を果たします。現在、IE10ではDXフィルターを削除しており、標準のSVGベースのフィルターに厳密に従っています。あなたは見てとることをお勧めします。この、このデモを
バルカンレイヴン2012

8
@vulcanravenこれは実際には「単なるCSS」ではありません。IEでアクティブスクリプトを無効にすると、フィルターが機能しなくなります。
robertc

3
@robertc、それはほぼ正しい。対照的に、ブラウザーでJavaScriptを無効にすると、Stackoverflowを含むほぼすべてのRIAが機能しなくなります(Web開発者がHTMLのみのバージョンのフォールバックを実装していない場合)。
バルカンレイヴン

2
ただ、CSSが使用stackoverflow.com/questions/286275/gray-out-image-with-css/... この質問に私の答えを取得します
坂田銀時

回答:


728

CSSフィルターのサポートがWebkitに導入されました。 これで、クロスブラウザソリューションが完成しました。

img {
  filter: gray; /* IE6-9 */
  -webkit-filter: grayscale(1); /* Google Chrome, Safari 6+ & Opera 15+ */
  filter: grayscale(1); /* Microsoft Edge and Firefox 35+ */
}

/* Disable grayscale on hover */
img:hover {
  -webkit-filter: grayscale(0);
  filter: none;
}
<img src="http://lorempixel.com/400/200/">


Internet Explorer 10はどうですか?

グレーのようなポリフィルを使用できます。


1
@CamiloMartin CSSフィルターはChrome 18以降でのみサポートされています
Salman von Abbas

2
更新: Google Chromeの最新の安定バージョン(19)でCSSフィルターがサポートされるようになりました。わーい!=)
サルマンフォンアッバス

6
Operaのソリューションはありますか?
ロスタム

23
それでは、IE10のソリューションは何ですか?
トムオージェ2013年

2
後世のために:@TomAuger、このQ&AにはIE10に関する特定の指示があります。
Barney

127

から続く brillout.comの回答、またローマNurikの答え、やや「ノーSVGの要件を緩和し、あなたは、単一のSVGファイルといくつかのCSSを使用してFirefoxで画像を不飽和化することができます。

SVGファイルは次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">
    <filter id="desaturate">
        <feColorMatrix type="matrix" values="0.3333 0.3333 0.3333 0 0
                                             0.3333 0.3333 0.3333 0 0
                                             0.3333 0.3333 0.3333 0 0
                                             0      0      0      1 0"/>
    </filter>
</svg>

それをresources.svgとして保存します。グレースケールに変更したいすべての画像でこれを再利用できます。

CSSでは、Firefox固有のfilterプロパティを使用してフィルターを参照します。

.target {
    filter: url(resources.svg#desaturate);
}

MS独自のものも追加したい場合は、グレースケールに変換する任意の画像にそのクラスを適用します(Firefox> 3.5、IE8で動作)

編集ここに記載さfilterれているSVGアプローチと連携してSalmanPKの回答で新しいCSS3 プロパティを使用することを説明する素晴らしいブログ投稿があります。そのアプローチを使用すると、次のようなものになります。

img.desaturate{
    filter: gray; /* IE */
    -webkit-filter: grayscale(1); /* Old WebKit */
    -webkit-filter: grayscale(100%); /* New WebKit */
    filter: url(resources.svg#desaturate); /* older Firefox */
    filter: grayscale(100%); /* Current draft standard */
}

その他のブラウザサポート情報はこちら


6
Webkitでこれを行います:-webkit-filter: grayscale(100%);次にこれ-webkit-filter: grayscale(0);を削除します。
SeanJA 2012年

@SeanJA更新のおかげで、WebKit は12月に
robertc '27

Linuxラップトップとwin7マシンの両方で、Chromeベータ版で表示されます。LinuxのChrome安定版では動作しないようです(ただし、LinuxのバージョンがWindowsの背後にある可能性があります)。
SeanJA 2012年

1
この方法はChromeでは問題なく機能しますが、Safariでは効果がありません。FFでは、ホバーするまで画像が見えなくなります。
colmtuite

85

Firefoxの場合、filter.svgファイルを作成する必要はありません。データURIスキームを使用できます。

最初の回答のcssコードを取り上げると、次のようになります。

filter: url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='matrix'%20values='0.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200%200%200%201%200'/></filter></svg>#grayscale"); /* Firefox 3.5+ */
filter: grayscale(100%); /* Current draft standard */
-webkit-filter: grayscale(100%); /* New WebKit */
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%); 
-o-filter: grayscale(100%);
filter: gray; /* IE6+ */

「utf-8」文字列をファイルエンコーディングで置き換えるように注意してください。

ブラウザは2番目のHTTPリクエストを実行する必要がないため、このメソッドは他のメソッドよりも高速である必要があります。


3
頭痛の種を省くためのメモ:YUI CompressorはデータURLのスペースを削除します。したがって、このソリューションを使用したい場合は、別の縮小機能を使用することを検討してください。
マルト

6
@Malteまたは、単にスペースを「%20」文字列に置き換えますか?
mquandalle 2013年

@mquandalle残念ながらIE10はfilter:grayblogs.msdn.com/b/ie/archive/2011/12/07/…を
Jedi.za

1
Firefoxでは、灰色が非常に薄いです。コントラストを上げる、または少し暗くする方法はありますか?他のブラウザは素晴らしいようです。
square_eyes 2013年

27

更新: IE10とIE11のJavaScriptポリフィルを含む完全なGitHubリポジトリに作成しました:https : //github.com/karlhorky/gray

私は元々SalmanPKの回答を使用していましたが、SVGファイルに必要な余分なHTTPリクエストを排除するために以下のバリエーションを作成しました。インラインSVGは、Firefoxバージョン10以降で機能し、10未満のバージョンは、グローバルブラウザー市場の1%も占めていません。

それ以来、このブログ投稿でソリューションを更新し続け、色へのフェードバックのサポート、SVGによるIE 10/11のサポート、およびデモの部分的なグレースケールを追加しています。

img.grayscale {
  /* Firefox 10+, Firefox on Android */
  filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='grayscale'><feColorMatrix type='matrix' values='0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0'/></filter></svg>#grayscale");

  /* IE 6-9 */
  filter: gray;

  /* Chrome 19+, Safari 6+, Safari 6+ iOS */
  -webkit-filter: grayscale(100%);
}

img.grayscale.disabled {
  filter: none;
  -webkit-filter: grayscale(0%);
}

14

JavaScriptを使用できる場合は、このスクリプトが必要な場合があります。これはクロスブラウザで動作し、今のところ私には問題なく動作しています。別のドメインから読み込んだ画像では使用できません。

http://james.padolsey.com/demos/grayscale/


11

今日も同じ問題が発生しました。私は最初にSalmanPKソリューションを使用しましたが、FFと他のブラウザーでは効果が異なることがわかりました。これは、変換行列がChrome / IEのフィルターのような明度ではなく明度でのみ機能するためです。驚いたことに、SVGの代替でより単純なソリューションもFF4 +で機能し、より良い結果を生み出すことがわかりました。

<svg xmlns="http://www.w3.org/2000/svg">
  <filter id="desaturate">
    <feColorMatrix type="saturate" values="0"/>
  </filter>
</svg>

CSSで:

img {
    filter: url(filters.svg#desaturate); /* Firefox 3.5+ */
    filter: gray; /* IE6-9 */
    -webkit-filter: grayscale(1); /* Google Chrome & Safari 6+ */
}

もう1つの注意点は、IE10が標準準拠モードで「filter:gray:」をサポートしていないため、機能するようにヘッダーで互換モードの切り替えが必要になることです。

<meta http-equiv="X-UA-Compatible" content="IE=9" />

2
より良い、よりシンプルなソリューションのようです-SalmanPKとmquandalleがソリューションをこれに更新した場合、良いでしょう。どうやら彼らが使用するマトリックス壊れている。ここ<BR> <BR>は、埋め込まれたデータのバージョンがあります: filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'saturate\' values=\'0\'/></filter></svg>#grayscale");
psdieは

11

CSSのみでグレースケールを実現する最も簡単な方法は、filterプロパティを使用することです。

img {
    -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
    filter: grayscale(100%);
}

プロパティはまだ完全にはサポートされておらず、-webkit-filterすべてのブラウザでサポートするためにプロパティが必要です。


7

CSS3やプロプライエタリ-webkit--moz-CSSのプロパティを使用しても、(まだ)可能ではないようです。

ただし、HTMLでSVGフィルターを使用した昨年6月の投稿を見つけました。現在のブラウザ(カスタムWebKitビルドをほのめかしたデモ)では利用できませんが、概念実証として非常に印象的です。


7

他の回答で無視されたIE10 +サポートについて質問している人は、次のCSSを確認してください。

img.grayscale:hover {
    filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'1 0 0 0 0, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0\'/></filter></svg>#grayscale");
}

svg {
    background:url(http://4.bp.blogspot.com/-IzPWLqY4gJ0/T01CPzNb1KI/AAAAAAAACgA/_8uyj68QhFE/s400/a2cf7051-5952-4b39-aca3-4481976cb242.jpg);
}

svg image:hover {
    opacity: 0;
}

このマークアップに適用:

<!DOCTYPE HTML>
<html>
<head>

    <title>Grayscaling in Internet Explorer 10+</title>

</head>
<body>

    <p>IE10 with inline SVG</p>
    <svg xmlns="http://www.w3.org/2000/svg" id="svgroot" viewBox="0 0 400 377" width="400" height="377">
      <defs>
         <filter id="filtersPicture">
           <feComposite result="inputTo_38" in="SourceGraphic" in2="SourceGraphic" operator="arithmetic" k1="0" k2="1" k3="0" k4="0" />
           <feColorMatrix id="filter_38" type="saturate" values="0" data-filterid="38" />
        </filter>
      </defs>
      <image filter="url(&quot;#filtersPicture&quot;)" x="0" y="0" width="400" height="377" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://4.bp.blogspot.com/-IzPWLqY4gJ0/T01CPzNb1KI/AAAAAAAACgA/_8uyj68QhFE/s1600/a2cf7051-5952-4b39-aca3-4481976cb242.jpg" />
    </svg>

</body>
</html>

その他のデモについては、IE testdriveのCSS3グラフィックセクションとこの古いIEブログhttp://blogs.msdn.com/b/ie/archive/2011/10/14/svg-filter-effects-in-ie10.aspxを確認してください。


7

Internet Explorerでは、filterプロパティを使用します。

WebkitとFirefoxでは、CSSだけで画像をデサチュレートする方法は現在ありません。そのため、クライアント側のソリューションにはキャンバスまたはSVGを使用する必要があります。

しかし、SVGを使用する方がエレガントだと思います。FirefoxとWebkitの両方で機能するSVGソリューションについては、私のブログ投稿を確認してください。http://webdev.brillout.com/2010/10/desaturate-image-without-javascript.html

そして厳密に言えば、SVGはHTMLなので、解決策は純粋なhtml + cssです:-)


こんにちはブリルアウト。あなたのグレースケールが実際にサファリで失敗することに気づきました。フォローアップはありますか?ありがとう
白鳥

1
SVGはHTMLではありません。それは全く異なるスペックです。
Camilo Martin

@CamiloMartinこれがHTML仕様のSVGです。
robertc

1
@robertcそのリンクはSVGをHTMLに配置することに関するものですが、ここにSVG仕様HTML仕様があります。両方が互いに(またはXMLに)似ているという事実は、それらが同じものであることを意味するわけではありません...
Camilo Martin

1
しかし、それはリファレンスの SVG仕様にリンクしています... SVGを定義していません。ブラウザがそれを解析するべきだとだけ言っています。その点では、JavaScriptやCSSに似ています。
Camilo Martin

6

これを行う新しい方法が、最近のブラウザーでしばらく利用可能になりました。

background-blend-modeを使用すると、興味深い効果を得ることができます。その1つがグレースケール変換です。

白い背景に設定されたluminosityの値は、それを可能にします。(ホバーで灰色で表示)

.test {
  width: 300px;
  height: 200px;
    background: url("http://placekitten.com/1000/750"), white; 
    background-size: cover;
}

.test:hover {
    background-blend-mode: luminosity;
}
<div class="test"></div>

明るさは画像から取得され、色は背景から取得されます。いつも白なので色はありません。

しかし、それだけではありません。

エフェクト設定3レイヤーをアニメーション化できます。1つ目は画像で、2つ目は白黒のグラデーションです。これに乗算ブレンドモードを適用すると、以前と同じように白い部分に白い結果が得られますが、黒い部分の元の画像は白で乗算すると白になり、黒で乗算しても効果がありません。

グラデーションの白い部分では、以前と同じ効果が得られます。グラデーションの黒い部分では、画像をそれ自体の上にブレンドしており、結果は変更されていない画像です。

ここで必要なのは、グラデーションを移動してこの効果を動的にすることだけです(カーソルをカラーで表示するには)

div {
    width: 600px;
    height: 400px;
}

.test {
    background: url("http://placekitten.com/1000/750"), 
linear-gradient(0deg, white 33%, black 66%), url("http://placekitten.com/1000/750"); 
    background-position: 0px 0px, 0px 0%, 0px 0px;
    background-size: cover, 100% 300%, cover;
    background-blend-mode: luminosity, multiply;
    transition: all 2s;
}

.test:hover {
    background-position: 0px 0px, 0px 66%, 0px 0px;
}
<div class="test"></div>

参照

互換性マトリックス


1
@Andy私は最新のブラウザで
vals

imgタグが画像に使用されていない場合、どのようにそれを適用できますかbackground: url()
Mohammad Elbanna 2018

1
@MohammadElbanna background-blend-modeの代わりにmix-blend-modeを使用する必要があります
vals

5
img {
    -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
    filter: grayscale(100%);
}

4

多分この方法はあなたを助ける

img {
    -webkit-filter: grayscale(100%); /* Chrome, Safari, Opera */
    filter: grayscale(100%);
}

w3schools.org


3

私がプロプライエタリなCSSプロパティを正しく使用したことを覚えていれば、実際にはIEを使用する方が簡単です。http://www.ssi-developer.net/css/visual-filters.shtmlFILTER: Grayからこれを試してください

による方法は、単に画像を透明にし、その背後に黒い背景があります。これがグレースケールであるとあなたが主張することができると私は確信しています。

JavaScriptを使いたくなかったのですが、Javascriptを使う必要があると思います。サーバーサイド言語を使用してそれを行うこともできます。


私はWindowsボックスさえ持っていないので、感謝しますが、それは私にはほとんど役に立ちません。
Ken

その場合、IEを備えた仮想マシンでそれを見て、axのメソッドを実装するか、キャンバスを使用できます...キャンバスを使用した大きな画像のグレースケールは、JavaScriptエンジンにかなりの負担がかかることに注意してください。
アレックス

7
filter: grayバージョン4以降、Internet Explorerに存在しています。彼らは彼らの製品のために多くのがらくたを取りました-正しく!-しかし、彼らはこのことで彼らの時代を本当に先んじていました
Pekka


2

現在のバージョン19.0.1084.46から、webkitのネイティブCSSフィルターのサポートが追加されました

したがって、-webkit-filter:grayscale(1)が機能し、webkitのSVGアプローチよりも簡単です...


2

以下は、不透明度を選択できるLESSのミックスインです。さまざまな割合でプレーンCSSの変数を自分で入力します。

ここではきちんとしたヒント、それはマトリックスに飽和型を使用するので、パーセンテージを変更するために特別なことをする必要はありません。

.saturate(@value:0) {
    @percent: percentage(@value);

    filter: url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='saturate'%20values='@value'/></filter></svg>#grayscale"); /* Firefox 3.5+ */
    filter: grayscale(@percent); /* Current draft standard */
    -webkit-filter: grayscale(@percent); /* New WebKit */
    -moz-filter: grayscale(@percent);
    -ms-filter: grayscale(@percent);
    -o-filter: grayscale(@percent);
}

次にそれを使用します:

img.desaturate {
    transition: all 0.2s linear;
    .saturate(0);
    &:hover {
        .saturate(1);
    }
}

2

古いFirefoxのプレフィックスを選択した場合、新しいFirefoxのプレフィックスを使用する必要がないため、フルに使用するためにそれほど多くのプレフィックスを使用する必要はありません。

したがって、十分に使用するには、次のコードを十分に使用してください。

img.grayscale {
    filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale"); /* Firefox 10+, Firefox on Android */
    filter: gray; /* IE6-9 */
    -webkit-filter: grayscale(100%); /* Chrome 19+, Safari 6+, Safari 6+ iOS */
}

img.grayscale.disabled {
    filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'1 0 0 0 0, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0\'/></filter></svg>#grayscale");
    filter: none;
    -webkit-filter: grayscale(0%);
}

2

他の回答を補足するものとして、SVGのマトリックスの頭痛のないFFの半分の方法で画像の彩度を下げることができます。

<feColorMatrix type="saturate" values="$v" />

どこ$vの間にある01。それは同等ですfilter:grayscale(50%);です。

ライブの例:

MDNのリファレンス


1

robertcの回答に基づく

このよう行列を使用する代わりに、カラー画像からグレースケール画像への適切な変換を取得するには:

0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0      0      0      1 0

次のような変換行列を使用する必要があります。

0.299 0.299 0.299 0
0.587 0.587 0.587 0
0.112 0.112 0.112 0
0     0     0     1

これは、RGBA(red-green-blue-alpha)モデルに基づくすべてのタイプのイメージで正常に機能するはずです。

マトリックスを使用する理由の詳細については、リンクに従ってrobertcの1つのチェックを投稿する可能性が高くなります。


0.3333が間違っていることに同意します。0.2126 0.7152 0.0722 0 0に相当するようです<fecolormatrix type="saturate" values="0">
Neil

:「ここであなたには、いくつかのC#やVBのコードを見つけることができると」へのリンクはこちらのインターネットアーカイブで見つけることができますweb.archive.org/web/20110220101001/http://www.bobpowell.net/...
thisgeek

「輝度と色差信号」へのリンクも壊れています。代替品が見つかりませんでした。
thisgeek

0

ひどいが実行可能な解決策の1つは、Flashオブジェクトを使用して画像をレンダリングします。これにより、Flashで可能なすべての変換が得られます。

場合は、ユーザーが最先端のブラウザを使用している場合のFirefox 3.5とSafari 4のサポートも(私は意志/やるのどちらかということを知らない)、あなたはCSSを調整することができ、カラープロファイルのグレースケールICCにそれを設定し、画像の属性をプロフィールURL。しかし、それは多くの場合です!


0

古いブラウザの代わりになる疑似要素またはインラインタグによって生成使用マスクにあってもよいです。

img(またはクリックや選択を必要としないテキスト領域)にカーソルを合わせるとrgba()またはtranslucide pngを介してカラースケールの効果を厳密に模倣できます。

単一のカラースケールは得られませんが、範囲外の色がシェーディングされます。

擬似要素を介して10の異なる色のコードペンでテストします。最後は灰色です。http://codepen.io/gcyrillus/pen/nqpDd(別の画像に切り替えるには再読み込みしてください



0

このjqueryプラグインを試してください。ただし、これは純粋なHTMLおよびCSSソリューションではありませんが、必要なことを達成するための遅延方法です。使用状況に最適になるようにグレースケールをカスタマイズできます。次のように使用します。

$("#myImageID").tancolor();

インタラクティブなデモがあります。あなたはそれで遊ぶことができます。

使い方のドキュメントを確認してください。とても簡単です。docs


0

Firefoxのグレースケールをパーセントで表示するには、代わりに飽和フィルターを使用します(「飽和」を検索)

filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='saturate'><feColorMatrix in='SourceGraphic' type='saturate' values='0.2' /></filter></svg>#saturate"

-1

あなた、または将来同様の問題に直面している他の誰かがPHPを利用できる場合。(私はあなたがHTML / CSSを言ったことを知っていますが、多分あなたはすでにバックエンドでPHPを使用しているでしょう)ここにPHPソリューションがあります:

私はそれをPHP GDライブラリから取得し、プロセスを自動化するためにいくつかの変数を追加しました...

<?php
$img = @imagecreatefromgif("php.gif");

if ($img) $img_height = imagesy($img);
if ($img) $img_width = imagesx($img);

// Create image instances
$dest = imagecreatefromgif('php.gif');
$src = imagecreatefromgif('php.gif');

// Copy and merge - Gray = 20%
imagecopymergegray($dest, $src, 0, 0, 0, 0, $img_width, $img_height, 20);

// Output and free from memory
header('Content-Type: image/gif');
imagegif($dest);

imagedestroy($dest);
imagedestroy($src);

?>

4
@Tom、元の質問の投票とお気に入りに基づくと、これが可能かどうか疑問に思ったのはOPだけではありません。確かに、この回答はルールを曲げる可能性がありますが、多くの人にとって役立つ回答に反対票を投じる意味がわかりません。
Michael Martin-Smucker

1
@トム、私はそれが質問に対する正確な返答ではないかもしれませんが、それは実際にはJavaScriptの「煩わしさ」なしでグレースケールの問題を「解決する」ので役立つかもしれません、多分彼はPHPについてさえ考慮も知らなかったかもしれませんGD、意図的な害はありません。@ mlms13それがまさにポイントでした、ありがとう:)
Trufa

それは、私の投稿から他のユーザーが恩恵を受けることができるということについての「考え」が私の悪いことです。謝罪@Trufa。
衝撃

3
それは私を助けました、他のいくつかの行き止まりの後で私を正しい軌道に乗せました。「imagefilter($ source、IMG_FILTER_GRAYSCALE);」を使用していることがわかりました しかし、はるかに良い結果が得られました。(PHP 5のみ)
chrismacp 2010

5
事実上トピックから外れているため、反対票が投じられました。サーバー側での画像のグレースケールは、CSS / HTMLとは完全に異なります。
Simon Steinberger
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.