SlideShare uma empresa Scribd logo
1 de 29
Baixar para ler offline
HTML5 Canvas で学ぶ
   アフィン変換
       2012/09/25 SWF 研究会#2
                    @a_bicky
自己紹介
•   Takeshi Arabiki
     ‣   社会人2年目の底辺 Web エンジニア

     ‣   Twitter & はてな: @a_bicky & id:a_bicky

•   お仕事
    JSX や JavaScript でコードを書いたり

•   興味など
    機械学習、自然言語処理、R

•   ブログ
    あらびき日記 http://d.hatena.ne.jp/a_bicky/
アフィン変換とは?
こういう変換とか




      ※アニメーションです
こういう変換とか




      ※アニメーションです
アフィン変換
ざっくりした意味
 平行移動を伴う線形変換
   ✓    0
            ◆       ✓           ◆✓       ◆       ✓        ◆
       x                a   c        x               tx
                =                            +
       y0               b   d        y               ty
                    線形変換                     平行移動


   0        1       0                10          1
     x0       a             c   tx     x
   @ y0 A = @ b             d   ty A @ y A
     1        0             0    1     1
同次座標系
 1つの行列で線形変換と平行移動を表すために次元を1つ増やす
Canvas によるアフィン変換
      0    0
               1   0           10      1
        x        a       c   tx     x
      @ y0 A = @ b       d   ty A @ y A
        1        0       0    1     1

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.transform(a, b, c, d, tx, ty);
ctx.drawImage(img, 0, 0);
拡大・縮小
                          0      1     0                10       1
                             x0        sx 0 0     x
                         0
                 sx = w /w @ y 0 A = @ 0 sy 0 A @ y A
  元の画像                  0    1          0 0 1     1
                      w              0      1
                    w                  sx x
                           x       = @ sy y A
                                         1
         0   h
     h
                           var canvas = document.getElementById("canvas");
      0                    var ctx = canvas.getContext("2d");
sy = h /h                  ctx.scale(sx, sy);
                 y         ctx.drawImage(img, 0, 0);
回転
               0   0
                       1   0                        10       1
                 x         cos     sin   0    x
               @ y 0 A = @ sin    cos    0 A@ y A
元の画像
                 1           0      0    1    1
                         0               1
                           x cos   y sin
           ✓   x       = @ x sin + y cos A
                                 1


               var canvas = document.getElementById("canvas");
               var ctx = canvas.getContext("2d");
               ctx.rotate(theta);
       y       ctx.drawImage(img, 0, 0);
平行移動
                 0    0
                          1   0               10       1
                   x        1 0           tx     x
                 @ y0 A = @ 0 1           ty A @ y A
元の画像
                   1        0 0            1     1
                          0               1
            tx              x + tx
       ty        x      = @ y + ty        A
                              1


                  var canvas = document.getElementById("canvas");
                  var ctx = canvas.getContext("2d");
                  ctx.translate(tx, ty);
            y     ctx.drawImage(img, 0, 0);
剪断
               0   0
                       1   0                      10        1
                 x           1     tan ⇥ 0     x
               @ y 0 A = @ tan       1    0 A@ y A
元の画像
                 1           0       0    1    1
                         0              1
                           x + y tan ⇥
           ↵   x       = @ x tan + y A
                                1

               var canvas = document.getElementById("canvas");
               var ctx = canvas.getContext("2d");
               ctx.transform(1, Math.tan(alpha),
                             Math.tan(beta), 1
       y                     0, 0);
               ctx.drawImage(img, 0, 0);
デモ
                      アフィン変換 デモ
時間がないのでやりません!
                  http://abicky.net/swf_study/2/


インタラクティブに変換して
みたい人は是非お試しください!
自作 Flash Player
   あるある
特定のシェイプが
表示されない><
い ?
                      て な
                 でき
              ース
           く パ
     正 し
 像 を
画
       変換行列がおかしい?
透過                         い ?
    度の                  か し
       問題?             お
                 序   が
              画順
            描
い ?
                      て な
                 でき
              ース
           く パ
     正 し
 像 を
画
       変換行列がおかしい?
透過                         い ?
    度の                  か し
       問題?             お
                 序   が
              画順
            描
Canvas では現在の変換行列を
  取得できない... orz
作った!
HTML5 の Canvas で getTransform が使えるようにしてみた - あらびき日記
          http://d.hatena.ne.jp/a_bicky/20120724/1343084686




                             ← ロードすると getTransform が使える
ここで問題
Canvas で
x, y 軸方向に2倍する
変換行列を適用してから
x, y 軸方向に1移動する
変換行列を適用すると
  どうなるか?
正しいのはどっち?
            1

        1




    1               1   2


1               1

                2
正しいのはどっち?
            1

        1




                    ○
    1               1   2


1               1

                2
正しいのはどっち?
正しいのはどっち?


   ○
最初 getTransform は
  逆になってた
      ><
簡単な解説
        元の座標系での値 スケール2倍の座標系での値
                                          2
    1           1   1                 1   1

1           1                   1
            1                 2 1




                         スケールを2倍した座標系で1移動する
           スケールを2倍する
                        (元の座標系では2移動することになる)


                                    スケールを2倍する
                              (移動した上での2倍なので
                               移動量も2倍になる)
                    まず1移動する
まとめ
まとめ
•   アフィン変換は平行移動伴う線形変換

•   Canvas で変換行列の状態を取得する getTransform を作った

•   複数の変換行列を適用する場合は最初に適用するものが
    最左にくる
参考
•   アフィン変換とは - 大人になってからの再学習

•   にゃあプロジェクト - ウェブログ - Matrixって何だお? (1)

•   アフィン変換 画像処理ソリューション

•   無職のプログラミング  [HTML5 Canvas]変形メソッド
    scale(),rotate(),translate() の実行順序

Mais conteúdo relacionado

Mais procurados

マルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことマルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことAmazon Web Services Japan
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?Moriharu Ohzu
 
SageMakerを使った異常検知
SageMakerを使った異常検知SageMakerを使った異常検知
SageMakerを使った異常検知Ryohei Yamaguchi
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれKumazaki Hiroki
 
Apache Kafka on Herokuを活用したイベント駆動アーキテクチャの設計と実装
Apache Kafka on Herokuを活用したイベント駆動アーキテクチャの設計と実装Apache Kafka on Herokuを活用したイベント駆動アーキテクチャの設計と実装
Apache Kafka on Herokuを活用したイベント駆動アーキテクチャの設計と実装Salesforce Developers Japan
 
AWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAkihiro Kuwano
 
イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)Yoshitaka Kawashima
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織Takafumi ONAKA
 
IAM Roles Anywhereのない世界とある世界(2022年のAWSアップデートを振り返ろう ~Season 4~ 発表資料)
IAM Roles Anywhereのない世界とある世界(2022年のAWSアップデートを振り返ろう ~Season 4~ 発表資料)IAM Roles Anywhereのない世界とある世界(2022年のAWSアップデートを振り返ろう ~Season 4~ 発表資料)
IAM Roles Anywhereのない世界とある世界(2022年のAWSアップデートを振り返ろう ~Season 4~ 発表資料)NTT DATA Technology & Innovation
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意Yoshitaka Kawashima
 
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)NTT DATA OSS Professional Services
 
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...NTT DATA Technology & Innovation
 
深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで
深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで
深層学習による自然言語処理入門: word2vecからBERT, GPT-3までYahoo!デベロッパーネットワーク
 
ここが良かったDatadog
ここが良かったDatadogここが良かったDatadog
ここが良かったDatadogtyamane
 
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)NTT DATA Technology & Innovation
 
アーキテクチャのレビューについて - JaSST Review '18
アーキテクチャのレビューについて - JaSST Review '18アーキテクチャのレビューについて - JaSST Review '18
アーキテクチャのレビューについて - JaSST Review '18Yusuke Suzuki
 
リクルートのWebサービスを支える共通インフラ「RAFTEL」
リクルートのWebサービスを支える共通インフラ「RAFTEL」リクルートのWebサービスを支える共通インフラ「RAFTEL」
リクルートのWebサービスを支える共通インフラ「RAFTEL」Recruit Technologies
 
爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話Kentaro Yoshida
 

Mais procurados (20)

マルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことマルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのこと
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
SageMakerを使った異常検知
SageMakerを使った異常検知SageMakerを使った異常検知
SageMakerを使った異常検知
 
Data-Centric AIの紹介
Data-Centric AIの紹介Data-Centric AIの紹介
Data-Centric AIの紹介
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
 
Apache Kafka on Herokuを活用したイベント駆動アーキテクチャの設計と実装
Apache Kafka on Herokuを活用したイベント駆動アーキテクチャの設計と実装Apache Kafka on Herokuを活用したイベント駆動アーキテクチャの設計と実装
Apache Kafka on Herokuを活用したイベント駆動アーキテクチャの設計と実装
 
AWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティス
 
イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
IAM Roles Anywhereのない世界とある世界(2022年のAWSアップデートを振り返ろう ~Season 4~ 発表資料)
IAM Roles Anywhereのない世界とある世界(2022年のAWSアップデートを振り返ろう ~Season 4~ 発表資料)IAM Roles Anywhereのない世界とある世界(2022年のAWSアップデートを振り返ろう ~Season 4~ 発表資料)
IAM Roles Anywhereのない世界とある世界(2022年のAWSアップデートを振り返ろう ~Season 4~ 発表資料)
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意
 
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
 
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
 
深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで
深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで
深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで
 
ここが良かったDatadog
ここが良かったDatadogここが良かったDatadog
ここが良かったDatadog
 
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
 
アーキテクチャのレビューについて - JaSST Review '18
アーキテクチャのレビューについて - JaSST Review '18アーキテクチャのレビューについて - JaSST Review '18
アーキテクチャのレビューについて - JaSST Review '18
 
NetflixにおけるPresto/Spark活用事例
NetflixにおけるPresto/Spark活用事例NetflixにおけるPresto/Spark活用事例
NetflixにおけるPresto/Spark活用事例
 
リクルートのWebサービスを支える共通インフラ「RAFTEL」
リクルートのWebサービスを支える共通インフラ「RAFTEL」リクルートのWebサービスを支える共通インフラ「RAFTEL」
リクルートのWebサービスを支える共通インフラ「RAFTEL」
 
爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話
 

Mais de Takeshi Arabiki

クックパッド特売情報 における自然言語処理 〜固有表現抽出を利用した検索システム〜
クックパッド特売情報 における自然言語処理 〜固有表現抽出を利用した検索システム〜クックパッド特売情報 における自然言語処理 〜固有表現抽出を利用した検索システム〜
クックパッド特売情報 における自然言語処理 〜固有表現抽出を利用した検索システム〜Takeshi Arabiki
 
Introduction to Japanese Morphological Analysis
Introduction to Japanese Morphological AnalysisIntroduction to Japanese Morphological Analysis
Introduction to Japanese Morphological AnalysisTakeshi Arabiki
 
R による文書分類入門
R による文書分類入門R による文書分類入門
R による文書分類入門Takeshi Arabiki
 
Rのデータ構造とメモリ管理
Rのデータ構造とメモリ管理Rのデータ構造とメモリ管理
Rのデータ構造とメモリ管理Takeshi Arabiki
 
Introduction to Favmemo for Immature Engineers
Introduction to Favmemo for Immature EngineersIntroduction to Favmemo for Immature Engineers
Introduction to Favmemo for Immature EngineersTakeshi Arabiki
 
Rのスコープとフレームと環境と
Rのスコープとフレームと環境とRのスコープとフレームと環境と
Rのスコープとフレームと環境とTakeshi Arabiki
 
twitteRで快適Rライフ!
twitteRで快適Rライフ!twitteRで快適Rライフ!
twitteRで快適Rライフ!Takeshi Arabiki
 
RではじめるTwitter解析
RではじめるTwitter解析RではじめるTwitter解析
RではじめるTwitter解析Takeshi Arabiki
 
R版Getopt::Longを作ってみた
R版Getopt::Longを作ってみたR版Getopt::Longを作ってみた
R版Getopt::Longを作ってみたTakeshi Arabiki
 
Rデータフレーム自由自在
Rデータフレーム自由自在Rデータフレーム自由自在
Rデータフレーム自由自在Takeshi Arabiki
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜Takeshi Arabiki
 
Rデバッグあれこれ
RデバッグあれこれRデバッグあれこれ
RデバッグあれこれTakeshi Arabiki
 
はじめてのまっぷりでゅ〜す
はじめてのまっぷりでゅ〜すはじめてのまっぷりでゅ〜す
はじめてのまっぷりでゅ〜すTakeshi Arabiki
 
TwitterのデータをRであれこれ
TwitterのデータをRであれこれTwitterのデータをRであれこれ
TwitterのデータをRであれこれTakeshi Arabiki
 
Twitterのデータを取得する準備
Twitterのデータを取得する準備Twitterのデータを取得する準備
Twitterのデータを取得する準備Takeshi Arabiki
 

Mais de Takeshi Arabiki (17)

開発の心得
開発の心得開発の心得
開発の心得
 
クックパッド特売情報 における自然言語処理 〜固有表現抽出を利用した検索システム〜
クックパッド特売情報 における自然言語処理 〜固有表現抽出を利用した検索システム〜クックパッド特売情報 における自然言語処理 〜固有表現抽出を利用した検索システム〜
クックパッド特売情報 における自然言語処理 〜固有表現抽出を利用した検索システム〜
 
Introduction to Japanese Morphological Analysis
Introduction to Japanese Morphological AnalysisIntroduction to Japanese Morphological Analysis
Introduction to Japanese Morphological Analysis
 
R による文書分類入門
R による文書分類入門R による文書分類入門
R による文書分類入門
 
Rのデータ構造とメモリ管理
Rのデータ構造とメモリ管理Rのデータ構造とメモリ管理
Rのデータ構造とメモリ管理
 
Introduction to Favmemo for Immature Engineers
Introduction to Favmemo for Immature EngineersIntroduction to Favmemo for Immature Engineers
Introduction to Favmemo for Immature Engineers
 
Rのスコープとフレームと環境と
Rのスコープとフレームと環境とRのスコープとフレームと環境と
Rのスコープとフレームと環境と
 
twitteRで快適Rライフ!
twitteRで快適Rライフ!twitteRで快適Rライフ!
twitteRで快適Rライフ!
 
RではじめるTwitter解析
RではじめるTwitter解析RではじめるTwitter解析
RではじめるTwitter解析
 
R版Getopt::Longを作ってみた
R版Getopt::Longを作ってみたR版Getopt::Longを作ってみた
R版Getopt::Longを作ってみた
 
Rデータフレーム自由自在
Rデータフレーム自由自在Rデータフレーム自由自在
Rデータフレーム自由自在
 
HMM, MEMM, CRF メモ
HMM, MEMM, CRF メモHMM, MEMM, CRF メモ
HMM, MEMM, CRF メモ
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
 
Rデバッグあれこれ
RデバッグあれこれRデバッグあれこれ
Rデバッグあれこれ
 
はじめてのまっぷりでゅ〜す
はじめてのまっぷりでゅ〜すはじめてのまっぷりでゅ〜す
はじめてのまっぷりでゅ〜す
 
TwitterのデータをRであれこれ
TwitterのデータをRであれこれTwitterのデータをRであれこれ
TwitterのデータをRであれこれ
 
Twitterのデータを取得する準備
Twitterのデータを取得する準備Twitterのデータを取得する準備
Twitterのデータを取得する準備
 

HTML5 Canvas で学ぶアフィン変換

  • 1. HTML5 Canvas で学ぶ アフィン変換 2012/09/25 SWF 研究会#2 @a_bicky
  • 2. 自己紹介 • Takeshi Arabiki ‣ 社会人2年目の底辺 Web エンジニア ‣ Twitter & はてな: @a_bicky & id:a_bicky • お仕事 JSX や JavaScript でコードを書いたり • 興味など 機械学習、自然言語処理、R • ブログ あらびき日記 http://d.hatena.ne.jp/a_bicky/
  • 4. こういう変換とか ※アニメーションです
  • 5. こういう変換とか ※アニメーションです
  • 6. アフィン変換 ざっくりした意味  平行移動を伴う線形変換 ✓ 0 ◆ ✓ ◆✓ ◆ ✓ ◆ x a c x tx = + y0 b d y ty 線形変換 平行移動 0 1 0 10 1 x0 a c tx x @ y0 A = @ b d ty A @ y A 1 0 0 1 1 同次座標系  1つの行列で線形変換と平行移動を表すために次元を1つ増やす
  • 7. Canvas によるアフィン変換 0 0 1 0 10 1 x a c tx x @ y0 A = @ b d ty A @ y A 1 0 0 1 1 var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.transform(a, b, c, d, tx, ty); ctx.drawImage(img, 0, 0);
  • 8. 拡大・縮小 0 1 0 10 1 x0 sx 0 0 x 0 sx = w /w @ y 0 A = @ 0 sy 0 A @ y A 元の画像 0 1 0 0 1 1 w 0 1 w sx x x = @ sy y A 1 0 h h var canvas = document.getElementById("canvas"); 0 var ctx = canvas.getContext("2d"); sy = h /h ctx.scale(sx, sy); y ctx.drawImage(img, 0, 0);
  • 9. 回転 0 0 1 0 10 1 x cos sin 0 x @ y 0 A = @ sin cos 0 A@ y A 元の画像 1 0 0 1 1 0 1 x cos y sin ✓ x = @ x sin + y cos A 1 var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.rotate(theta); y ctx.drawImage(img, 0, 0);
  • 10. 平行移動 0 0 1 0 10 1 x 1 0 tx x @ y0 A = @ 0 1 ty A @ y A 元の画像 1 0 0 1 1 0 1 tx x + tx ty x = @ y + ty A 1 var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.translate(tx, ty); y ctx.drawImage(img, 0, 0);
  • 11. 剪断 0 0 1 0 10 1 x 1 tan ⇥ 0 x @ y 0 A = @ tan 1 0 A@ y A 元の画像 1 0 0 1 1 0 1 x + y tan ⇥ ↵ x = @ x tan + y A 1 var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.transform(1, Math.tan(alpha), Math.tan(beta), 1 y 0, 0); ctx.drawImage(img, 0, 0);
  • 12. デモ アフィン変換 デモ 時間がないのでやりません! http://abicky.net/swf_study/2/ インタラクティブに変換して みたい人は是非お試しください!
  • 13. 自作 Flash Player あるある
  • 15. い ? て な でき ース く パ 正 し 像 を 画 変換行列がおかしい? 透過 い ? 度の か し 問題? お 序 が 画順 描
  • 16. い ? て な でき ース く パ 正 し 像 を 画 変換行列がおかしい? 透過 い ? 度の か し 問題? お 序 が 画順 描
  • 17. Canvas では現在の変換行列を 取得できない... orz
  • 18. 作った! HTML5 の Canvas で getTransform が使えるようにしてみた - あらびき日記 http://d.hatena.ne.jp/a_bicky/20120724/1343084686 ← ロードすると getTransform が使える
  • 20. Canvas で x, y 軸方向に2倍する 変換行列を適用してから x, y 軸方向に1移動する 変換行列を適用すると どうなるか?
  • 21. 正しいのはどっち? 1 1 1 1 2 1 1 2
  • 22. 正しいのはどっち? 1 1 ○ 1 1 2 1 1 2
  • 25. 最初 getTransform は 逆になってた ><
  • 26. 簡単な解説 元の座標系での値 スケール2倍の座標系での値 2 1 1 1 1 1 1 1 1 1 2 1 スケールを2倍した座標系で1移動する スケールを2倍する (元の座標系では2移動することになる) スケールを2倍する (移動した上での2倍なので 移動量も2倍になる) まず1移動する
  • 28. まとめ • アフィン変換は平行移動伴う線形変換 • Canvas で変換行列の状態を取得する getTransform を作った • 複数の変換行列を適用する場合は最初に適用するものが 最左にくる
  • 29. 参考 • アフィン変換とは - 大人になってからの再学習 • にゃあプロジェクト - ウェブログ - Matrixって何だお? (1) • アフィン変換 画像処理ソリューション • 無職のプログラミング  [HTML5 Canvas]変形メソッド scale(),rotate(),translate() の実行順序