ぬの部屋(仮)
nu-no-he-ya
  • 1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
         12
    3456789
    10111213141516
    17181920212223
    2425262728  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
       1234
    567891011
    12131415161718
    19202122232425
    26272829   
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28      
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
    1234567
    891011121314
    15161718192021
    22232425262728
           
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
         12
    3456789
    10111213141516
    17181920212223
    242526272829 
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
        123
    45678910
    11121314151617
    18192021222324
    25262728   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    15161718192021
    293031    
           
         12
    3456789
    10111213141516
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
          1
    2345678
    9101112131415
    16171819202122
    232425262728 
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
  • ImageMagick+ffmpeg+Pythonで比較動画を作る

    0.ImageMagickで画像を横に並べる方法

    magick convert +append  [画像1ファイル名]   [画像2ファイル名]   [出力ファイル名]

    具体例:

    magick convert +append glass.png metalic.png ret.jpg

    1.Pythonで「ディレクトリ内の全ての画像に対して」ImageMagickをかける

    上記、magickのappendを、ディレクトリの中の全ての画像に対して行う関数を作成する。

    このスクリプトで"glass/"ディレクトリと"metalic/"ディレクトリ内の連番画像をappendでつなげて"appends/"ディレクトリへ保存する

    import subprocess  # コマンドラインを実行する
    import os          # パス文字列の操作など
    import glob        # ファイル一覧取得など
    
    ############################################
    ############################################
    
    ##
    # @brief 画像データを横に二つ並べる処理を全ての画像に対して行う
    # @param [in] dir_left 左側に配置する画像が存在するディレクトリ
    # @param [in] dir_right 右側に配置する画像が存在するディレクトリ
    # @param [in] dir_out 出力先のディレクトリ
    def image_append(dir_left , dir_right , dir_out):
    
      # 各ディレクトリの中のファイル一覧
      L_images = glob.glob(dir_left  + "/*.png", recursive=True)
      R_images = glob.glob(dir_right + "/*.png", recursive=True)
    
      # L_images,R_imagesのリストの要素をそれぞれiL,iRとして
      for(iL,iR) in zip(L_images,R_images):
      
        # 拡張子なしの left側のファイル名を取得
        oname = os.path.splitext(os.path.basename(iL))[0]
        
        # 出力ファイル名作成
        opathname = dir_out + "/" + oname + ".png"
        
        
        # コマンド作成
        command = "magick convert +append " + iL + " " + iR + " " + opathname
    
        # 作成したコマンドの確認
        print(command)
        
        # コマンドの実行
        subprocess.call(command)
    
    
    ############################################
    ############################################
    
    # 連番画像作成 引数は全てディレクトリ名
    image_append("glass" , "metalic" , "appends")
    

    2.連番画像を動画にするffmpegをPythonから呼び出す

    これ単体ならわざわざPythonから呼び出す必要はないが、上記スクリプトに続けて呼び出したいのでPythonからcallする。

    import subprocess  # コマンドラインを実行する
    import os          # パス文字列の操作など
    import glob        # ファイル一覧取得など
    
    
    ############################################
    ############################################
    
    ##
    # @brief 連番画像から動画を作成
    # @param [in] source 画像の場所とファイル名のパターン
    # @param [in] outFileName 出力ファイル名
    # @param [in] startNumber 画像の連番の開始番号
    def mp4out(source,outFileName,startNumber):
    
      # コマンド作成
      command = f'ffmpeg -start_number {startNumber} -r 15 -i {source} -vcodec libx264 -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" -framerate 60 {outFileName}'
    
      # コマンドの実行
      subprocess.call(command)
    
    
    ############################################
    ############################################
    
    
    # 動画作成 ファイル名、出力ファイル名、連番の最初の番号
    mp4out("appends/%04d.png","out.mp4",1)
    

    3.まとめ

    構成

    C:\TEST\DATA
    │  compmv.py ... pythonスクリプト
    │  out.mp4   ... ffmpegで生成した動画ファイル。mp4outで生成される
    │
    ├─appends
    │      0000.png
    │      0001.png
    │      0002.png
    │      0003.png
    │      0004.png
    │      .... 結合済み画像 image_appendで出力される
    │
    ├─glass
    │      0001.png
    │      0002.png
    │      0003.png
    │      0004.png
    │      .... 連番画像1
    │
    └─metalic
            0001.png
            0002.png
            0003.png
            0004.png
            .... 連番画像2
    
    

    スクリプト全体

    import subprocess  # コマンドラインを実行する
    import os          # パス文字列の操作など
    import glob        # ファイル一覧取得など
    
    ############################################
    ############################################
    
    
    ##
    # @brief 画像データを横に二つ並べる処理を全ての画像に対して行う
    # @param [in] dir_left 左側に配置する画像が存在するディレクトリ
    # @param [in] dir_right 右側に配置する画像が存在するディレクトリ
    # @param [in] dir_out 出力先のディレクトリ
    def image_append(dir_left , dir_right , dir_out):
    
      # 各ディレクトリの中のファイル一覧
      L_images = glob.glob(dir_left  + "/*.png", recursive=True)
      R_images = glob.glob(dir_right + "/*.png", recursive=True)
    
      # L_images,R_imagesのリストの要素をそれぞれiL,iRとして
      for(iL,iR) in zip(L_images,R_images):
      
        # 拡張子なしの left側のファイル名を取得
        oname = os.path.splitext(os.path.basename(iL))[0]
        
        # 出力ファイル名作成
        opathname = dir_out + "/" + oname + ".png"
        
        
        # コマンド作成
        command = "magick convert +append " + iL + " " + iR + " " + opathname
    
        # 作成したコマンドの確認
        print(command)
        
        # コマンドの実行
        subprocess.call(command)
    
    
          
    ############################################
    ############################################
    
    
    ##
    # @brief 連番画像から動画を作成
    # @param [in] source 画像の場所とファイル名のパターン
    # @param [in] outFileName 出力ファイル名
    # @param [in] startNumber 画像の連番の開始番号
    def mp4out(source,outFileName,startNumber):
    
      # コマンド作成
      command = f'ffmpeg -start_number {startNumber} -r 15 -i {source} -vcodec libx264 -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" -framerate 60 {outFileName}'
    
      # コマンドの実行
      subprocess.call(command)
    
    ############################################
    ############################################
    
    # 連番画像作成
    image_append("glass" , "metalic" , "appends")
    
    # 動画作成
    mp4out("appends/%04d.png","out.mp4",1)
    

    結果

    ImageMagick + ffmpeg + Pythonでスライドショー的なmp4動画を作る

    ImageMagickで画像サイズを変更、ffmpegで連番画像を動画に変換。

    その一連の作業をPythonスクリプトで行う。

    create_slideshow_movie.py

    # usage:
    # srcdir dstdir [0/1/2]
    # 0 ... 連番画像作成 + 動画作成
    # 1 ... 連番画像作成
    # 2 ... 動画作成
    
    import subprocess
    
    import sys
    import os
    import shutil
    import glob
    #import random
    
    ############################################
    
    # コマンドライン引数
    args = sys.argv
    
    # ディレクトリを二つ取得
    dir_in   = args[1]
    dir_out  = args[2]
    mode     = int(args[3])
    
    ############################################
    
    # 入力画像一覧
    file_name_list = glob.glob(dir_in + "/*.*", recursive=True)
    
    if mode==0 or mode==1:
    
      index=0
      
      for infile in file_name_list:
        
        sindex = str(index).zfill(8)
        index += 1
        
        # 変換後の画像サイズ
        xysize = "426x240" # "1920x1080"
        
        # 拡張子抜きのファイル名
        resultname = os.path.splitext(os.path.basename(infile))[0]
        
        # 出力ファイル名作成
        outfile = dir_out + "/" + sindex + ".jpg"
        
        # ImageMagickのコマンド作成
        cmd = "magick " + infile + " -gravity center -background gray -resize " + xysize + " -extent " + xysize + " " + outfile
    
        # ImageMagick実行
        subprocess.call(cmd)
    
    if mode==0 or mode==2:
    
      # https://qiita.com/livlea/items/a94df4667c0eb37d859f
      # 連番画像を0.2fps(5秒で1枚)の動画と考えて、
      # それを15fps(1秒に15枚)の動画として作成。結果、5秒間に15x5枚同じ画像を表示する動画となる。
      subprocess.call('ffmpeg -framerate 0.2 -i ' + dir_out + '/' + '%08d.jpg' + ' -vcodec libx264 -pix_fmt yuv420p -r 15 out.mp4')
    

    こんなスクリプトを作って、以下のように実行する。

    >python create_slideshow_movie.py src dst 0

    実行結果:

    ImageMagickでアスペクトを維持して画像サイズを変更、必要なら余白を加える

    magick input.jpg -gravity center -background black -resize 640x360 -extent 640x360 out.jpg

    -gravityでセンタリング、-resizeでスケーリング、-extentで切り取る範囲、-backgroundで余白の色。

    -resizeはデフォルトでアスペクト比を維持するので、-resizeで指定した画像サイズがそのまま結果となるとは限らない。そこで-extentを併用する。

    -resizeによってスケーリングの範囲内に必ず画像が収まるので、結果画像(切り出す範囲)を-extentで指定する。-resizeのw,hよりextentのw,hの方が大きかった部分は、backgroundで塗りつぶされる。

    WordPressのコメント欄から名前とURIを消す話

    要約

    ・コメント投稿時、ユーザ名/URI入力欄が表示されないようにする

    ・コメント表示時、万が一ユーザ名/URIデータがあっても表示されないようにする

    コメント投稿時 入力欄を削除

    入力欄を表示されないようにするため、functions.phpに以下を追記する

    <?php
    
    /*コメント欄から各項目を削除*/
    
    function hide_comment_fields_author($defaults){
      $defaults['fields']['author'] = '';
      return $defaults;
    }
    add_filter( 'comment_form_defaults', 'hide_comment_fields_author');

    function hide_comment_fields_email($defaults){
      $defaults['fields']['email'] = '';
      return $defaults;
    }
    add_filter( 'comment_form_defaults', 'hide_comment_fields_email');

    function hide_comment_fields_url($defaults){
      $defaults['fields']['url'] = '';
      return $defaults;
    }
    add_filter( 'comment_form_defaults', 'hide_comment_fields_url');
    /*コメント欄から各項目を削除 ここまで*/
    
    ?>
    

    参考サイト。以下では上記処理を一括指定する方法が公開されている。というか、comment_form_defautsに$defaults['fields'][***]を指定する関数を指定しているので一つにまとめられる。

    コメント表示時、名前/URI情報を表示しない

    仮に情報としてこれらが入力されていても、表示されないようにする。

    functions.php 側

    まずfunctions.php側でコメント表示時に指定するコールバック関数を作成。

    この時、URLや投稿者名を取得して表示する箇所を実装しないでおく。

    なおついでアバターの記述も無効化した。

    <?php 
    
    /* comments.phpで呼び出すwp_list_commentsに指定するコールバック関数 */
    function mytheme_comment($comment, $args, $depth) {
       $GLOBALS['comment'] = $comment; ?>
       <li <?php comment_class(); ?> id="li-comment-<?php comment_ID() ?>">
         <div id="comment-<?php comment_ID(); ?>">
          <div class="comment-author vcard">
             <?php /*アバターも無効化*/ /*echo get_avatar($comment,$size='48',$default='<path_to_url>' );*/ ?>
             <?php /*コメント投稿時指定のURLを非表示*/ /*echo get_comment_author_link( $comment_ID );*/ ?>
             <?php /*コメント投稿時指定の投稿者名を非表示*/ /*printf(__('<cite class="fn">%s</cite> <span class="says">より:</span>'), get_comment_author())*/ ?>
          </div>
          <?php if ($comment->comment_approved == '0') : ?>
             <em><?php _e('Your comment is awaiting moderation.') ?></em>
             <br />
          <?php endif; ?>
    
          <div class="comment-meta commentmetadata"><a href="<?php echo htmlspecialchars( get_comment_link( $comment->comment_ID ) ) ?>"><?php printf(__('%1$s at %2$s'), get_comment_date(),  get_comment_time()) ?></a><?php edit_comment_link(__('(Edit)'),'  ','') ?></div>
    
          <?php comment_text() ?>
    
          <div class="reply">
             <?php comment_reply_link(array_merge( $args, array('depth' => $depth, 'max_depth' => $args['max_depth']))) ?>
          </div>
         </div>
    <?php
            }
    /* comments.phpで呼び出すwp_list_commentsに指定するコールバック関数 ここまで*/
    
    ?>
    

    comments.php 側

    comments.php側では、作成した関数をwp_list_commentsのコールバックに指定する。

    <?php
    if (post_password_required()) {
      return;
    }
    ?>
    
    <div id="comments">
    <?php if (have_comments()) :?>
      <h3 id="comments-count"><?php echo get_comments_number().' 件のコメント'; ?></h3>
      <ul id="comments-list">
      <?php wp_list_comments(array(
          'avatar_size'=>48,
          'style'=>'ul',
          'type'=>'all',
          'callback'=>'mytheme_comment'
        )); 
      ?>
        
      </ul>
    <?php if (get_comment_pages_count() > 1) : ?>
      <ul id="comments-pagination">
        <li id="prev-comments"><?php previous_comments_link('&lt;&lt; 前のコメント'); ?></li>
        <li id="next-comments"><?php next_comments_link('次のコメント &gt;&gt;'); ?></li>
      </ul>
    <?php endif; endif; ?>
    <?php comment_form(); ?>
    </div><!-- comments -->
    

    参考サイト。

    https://deluxeblogtips.com/wordpress-remove-author-link-in/

    あとがき

    コメント欄でトラブルがあったのでこれを機に消してしまうことにした。

    実際ほぼすべての状況において名前やメールアドレスを「サイト管理者が」持つことは有害無益なので入力欄などないほうがいい。

    libwebpを使ってみる(Decode)

    デコード。webpファイルを読み込み、ppmファイルに変換する。なおアルファ付き画像は扱わない。

    #include <fstream>
    
    #include "ppmP3_read.hpp"
    
    #include <vector>
    
    #include <webp/decode.h>
    
    #pragma comment(lib,"libwebp.lib")
    
    
    
    void ppmP3_write(
      const char* const fname,
      const int width,
      const int height,
      const unsigned char* const p,
      const int vmax
    );
    
    
    int main()
    {
      // ファイルの画像の格納先
      std::vector<std::uint8_t> image;
    
    
      ///////////////////////////////////
      // webp形式の画像データをファイルから読み込む
      std::ifstream ifs(
        "C:\\test\\a.webp", 
        std::ios::binary);
      ifs.seekg(0, std::ios::end);
      long long int size = ifs.tellg();
      ifs.seekg(0);
    
      // ファイル読み込み
      image.resize(size);
      ifs.read((char*)image.data(), size);
    
      //ファイルのデータサイズ
      const size_t datasize = image.size();
      ///////////////////////////////////
    
      // 画像データの情報の格納先
      int width;
      int height;
      uint8_t* rgb = nullptr;
    
      // 画像情報を取得する構造体
      WebPBitstreamFeatures info;
    
      // 画像情報を取得
      WebPGetFeatures(
        image.data(),
        datasize,
        &info
      );
      ///////////////////////////////////
      // 画像情報を表示
      printf("alpha   : %s\n", info.has_alpha?"true":"false");
      printf("format  : %s\n",
        (info.format == 0) ? "undefined":
        ((info.format == 1) ? "lossy" : "lossless"));
      printf("animation:%s\n", info.has_animation ? "true" : "false");
      ///////////////////////////////////
    
      if (info.has_alpha != 0) {
    
        // WebPDecodeRGBA でRGBAのデータ列に変換
      }
      else {
    
        // RGBのデータ列に変換。戻り値がRGGデータ
        rgb = WebPDecodeRGB(
          image.data(),
          datasize,
          &width,
          &height
        );
      }
    
      ///////////////////////////////////
    
      ppmP3_write("C:\\test\\fromwebp.ppm",
        width, height,
        rgb,
        255);

    
          
      // libWebPが確保したメモリの解放
      WebPFree(rgb);
    }
    
    //! @brief PPM(RGB各1byte,カラー,テキスト)を書き込む
    //! @param [in] fname ファイル名
    //! @param [in] width 画像の幅
    //! @param [in] height 画像の高さ
    //! @param [in] p 画像のメモリへのアドレス
    //! @param [in] vmax 全てのRGBの中の最大値。普通の画像なら255
    //! @details RGBRGBRGB....のメモリを渡すと、RGBテキストでファイル名fnameで書き込む
    void ppmP3_write(
      const char* const fname,
      const int width,
      const int height,
      const unsigned char* const p,
      const int vmax
    ) {
    
      FILE* fp = fopen(fname, "wb");
      fprintf(fp, "P3\n%d %d\n%d\n", width, height, vmax);
    
      size_t k = 0;
      for (size_t i = 0; i < (size_t)height; i++) {
        for (size_t j = 0; j < (size_t)width; j++) {
          fprintf(fp, "%d %d %d ",
            p[k * 3 + 0],
            p[k * 3 + 1],
            p[k * 3 + 2]
          );
          k++;
        }
        fprintf(fp, "\n");
      }
    
      fclose(fp);
    }
    

    libwebpを使ってみる(Encode , Lossy)

    libwebpを使ってみる(Encode , Lossless)

    小規模な画像をLossyで保存すると色がかなり悲惨なことになる(QualityFactor==100.0でも)。

    なのでテストのため少し大きめのPPMを読み込んで変換する。

    #include "ppmP3_read.hpp"
    
    #include <vector>
    
    #include <webp/encode.h>
    
    #pragma comment(lib,"libwebp.lib")
    
    
    // https://suzulang.com/ppmp3_read-memalloc-ver/
    #include "ppmP3_read.hpp"
    
    // https://www.study.suzulang.com/2dcg-functions/nbyte-data-type
    #include "NByteData.hpp"
    
    
    
    int main()
    {
      using PixelT = NByteData<3>;
    
      std::vector<PixelT> rgbdata;
    
      // 画像読み込み
      int width;
      int height;
      int vmax;
    
      // rgb画像読み込み
      ppmP3_read(
        "C:\\data\\b.ppm",
        &width,
        &height,
        &vmax,
        [&rgbdata](const size_t pixelcount) {
        rgbdata.resize(pixelcount);
        return (unsigned char*)&rgbdata[0];
      }
      );
    
      // 非可逆圧縮の品質 0.0f ~ 100.0f
      float quality_factor = 50.0f;
    
      uint8_t* output = 0;
    
      // 非可逆圧縮
      size_t size = WebPEncodeRGB(
        rgbdata.data()->data(),
        width,
        height,
        width * 3,      // stride 一行のメモリサイズ
        quality_factor, // 品質
        &output
      );
      printf("%zu", size);
    
    
      FILE* fp = fopen("C:\\data\\test-lossy-rgb.webp", "wb");
      fwrite(output, 1, size, fp);
      fclose(fp);
    
    
      WebPFree(output);
    
    }
    

    libwebpを使ってみる(Encode , Lossless)

    libwebpを使って.webpファイルを出力してみる。

    公式からダウンロード・展開

    https://developers.google.com/speed/webp/download?hl=ja

    展開する。

    マニュアルは以下:

    https://developers.google.com/speed/webp/docs/api

    LosslessでRGB画像出力

    #pragma warning(disable:4996)
    
    #include <vector>
    
    #include <webp/encode.h>
    
    #pragma comment(lib,"libwebp.lib")
    
    int main()
    {
      // 作成したwebp形式のデータのアドレスを受け取るポインタ
      uint8_t* output = 0;
    
      // 2×3のRGB画像を作成
      std::vector<uint8_t> rgbdata = {
        255,  0,  0 /**/,   0,255,  0,
          0,  0,255 /**/, 255,255,  0,
        255,  0,255 /**/,   0,255,255
      };
      int width = 2;
      int height = 3;
    
      size_t size = WebPEncodeLosslessRGB(
        rgbdata.data(), // 変換したい画像へのポインタ
        width,          // 画像幅  ピクセル数
        height,         // 画像高さ ピクセル数
        width * 3,      // stride 一行のメモリサイズ
        &output         // データを受け取るポインタのアドレス
      );
    
      // 戻り値はoutputのバイト数
      printf("%zu", size);
    
      // ファイル出力
      FILE* fp = fopen("C:\\dev\\test-lossless-rgb.webp", "wb");
      fwrite(output, 1, size, fp);
      fclose(fp);
    
      // libwebpが確保したメモリの解放
      WebPFree(output);
    
    }
    

    LosslessでRGBA画像出力

    RGBAも可。

    #pragma warning(disable:4996)
    
    #include <vector>
    
    #include <webp/encode.h>
    
    #pragma comment(lib,"libwebp.lib")
    
    
    int main()
    {
      uint8_t* output = 0;
    
      std::vector<uint8_t> rgbdata = {
        255,  0,  0, 255 /**/,   0,255,  0, 212,
          0,  0,255, 170 /**/, 255,255,  0, 127,
        255,  0,255,  85 /**/,   0,255,255,  42
      };
      int width = 2;
      int height = 3;
    
      size_t size = WebPEncodeLosslessRGBA(
        rgbdata.data(),
        width,
        height,
        width * 4, // stride 一行のメモリサイズ
        &output
      );
      printf("%zu", size);
    
    
      FILE* fp = fopen("C:\\dev\\test-lossless-rgba.webp", "wb");
      fwrite(output, 1, size, fp);
      fclose(fp);
    
    
      WebPFree(output);
    
    }
    

    塗りつぶし Flood fill(3)再帰なし版を真面目に実装

    以前作ったFloodFill。無理やり再帰なしにしたが、今度はちゃんとスタックを使ってまともに再帰なし版を書いた。

    #pragma once
    
    
    #pragma once
    
    #include "NByteData.hpp"
    #include <stack>
    
    using uc3T = NByteData<3>;
    
    //! @brief 座標計算などを行う補助クラス
    class accessor {
      int width;
      int height;
    public:
      void set(int Width, int Height) {
        width = Width;
        height = Height;
      }
      bool is_in(const int x, const int y) {
        if (x < 0 || y < 0 || x >= width || y >= height)
          return false;
    
        return true;
    
      }
      size_t get_pos(const int x, const int y) {
        return (size_t)y * width + (size_t)x;
      }
    
    };
    
    
    //! @brief floodfill本体
    //! @param [in] x 対象の画素のX座標
    //! @param [in] y 対象の画素のY座標
    //! @param [in] targetcolor 塗りつぶし対象の色
    //! @param [in] replacementcolor 塗りつぶし結果の色
    //! @param [in,out] img 対象の画像データ
    //! @param [in] acc 画素の座標等を求めたりする補助クラスのインスタンス
    void ff_fill(
      int x,
      int y,
      uc3T targetcolor,
      uc3T replacementcolor,
      uc3T* img,
      accessor* acc) {
    
      using xyT = std::pair<int, int>;
    
      std::stack<xyT> stack;
    
      stack.push({ x,y });
    
      while (stack.empty() != true) {
    
        xyT xy = stack.top();
        stack.pop();
        x = xy.first;
        y = xy.second;
    
        if (acc->is_in(x, y) == false)
          continue;
    
        uc3T* node = &img[acc->get_pos(x,y)];
    
        if (*node != targetcolor) {
          continue;
        }
    
        *node = replacementcolor;
    
        stack.push({ x + 1, y });
        stack.push({ x - 1, y });
        stack.push({ x, y - 1 });
        stack.push({ x, y + 1 });
      }
    
      return;
    
    }
    //! @brief floodfillエントリポイント
    //! @param [in] seedx 塗りつぶし開始点
    //! @param [in] seedy 塗りつぶし開始点
    //! @param [in] replacementcolor 塗りつぶし結果の色
    //! @param [in,out] img 対象の画像データ
    //! @param [in] Width 画像幅(画素数)
    //! @param [in] Height 画像高さ(画素数)
    void f_fill(
      int seedx, int seedy,
      uc3T replacementcolor,
      uc3T* img,
      int Width, int Height) {
    
      accessor acc;
      acc.set(Width, Height);
      if (acc.is_in(seedx, seedy) == false)
        return;
    
      uc3T targetcolor = img[acc.get_pos(seedx, seedy)];
    
      ff_fill(seedx, seedy, targetcolor, replacementcolor, img, &acc);
    
    }
    

    関連

    塗りつぶし Flood fill(1)

    塗りつぶし Flood fill(2)再帰関数を無理やり不使用にする

    塗りつぶし Flood fill(3)再帰なし版を真面目に実装

    WordPress + Gantry 5 ページごとのスタイルを設定

    前回Gantry 5を有効にするまでやったので、各ページごとにスタイル等を設定していく方法を調べた。

    WordPressでGantry 5 を使う

    まず、設定の変更をわかりやすくするために、メニューを作成する。

    カテゴリーアーカイブのページで表示されるメニュー、シングルページで表示されるメニュー、...と言った具合で作成しておく。

    次に、アウトラインを作成する。

    カテゴリーアーカイブのページ用のアウトライン、シングルページ 用のアウトライン 、...と言った具合で作成しておく。

    ここで、一例としてカテゴリアーカイブのアウトラインを、カテゴリアーカイブのページに適用する事を考える。

    まず、カテゴリアーカイブページのアウトラインがちゃんとカテゴリアーカイブのページで表示される設定になっている事をわかりやすくするためにメニューを設定しておく。

    次に、Categoryarchiveアウトラインを選択した状態で、Assignmentsへ行き、Pate Contextの「Category Archive Page」のスイッチをONにする。

    この設定で、Category Archive Pageに対しては、Categoryarchiveアウトラインを使用する、事になる。

    この状態で設定を保存しカテゴリアーカイブを見てみると、ちゃんとアウトラインが反映されている。

    ここで、例えばカテゴリアーカイブページでは本文を表示させないでタイトル一覧だけにしたいというような変更を加えてみる。

    今度はContentへ行き、Archiveの項目の「Content」のスイッチをOFFにする。これでコンテンツ、つまり本文が表示されなくなる。ついでに、「Comments Meta」もOFFにし、No comments という部分も非表示にしてみる。

    設定を保存して更新すると、本文が消えているのがわかる。

    WordPressでGantry 5 を使う

    Gantry 5 はテーマフレームワーク。Wordpress版もあるらしい。

    プラグインから検索してインストールもできる(Gantry 5 Framework)のだが、テーマもインストールしなければならず、テーマと本体のバージョンの違いによってはうまく動かないので公式からダウンロードしたほうがいい。

    公式からプラグイン本体とテーマを一つ以上ダウンロードする

    https://gantry.org/downloads

    プラグインとテーマをインストールする

    テーマを有効化するとテーマの設定項目が表示される。