見出し画像

Googleアイコン(SVG)をpng画像に変換して活用webixで一覧管理しますNo.063

Googleアイコンって知っていますか?SVGフォーマットでサイズや色を指定してきれいな画像をダウンロードし、利用することができます。
以下のサイトで画面操作で利用できます。

アイコンの数が2000以上あるので、探すのがけっこう大変です。
一括でダウンロードもできますが、ZIP形式で3.9GBもあり、フォルダ構成が深いので、こちらも探すのが大変。
今回、Googleマップのマーカーシンボルを自分で指定した画像にして表示することを計画しており、そのシンボルを集めるためにGoogleアイコンを使うことにしました。
但し、100個くらいのアイコンを抽出しようとすると、時間もかかるので、まずは、アイコンを一覧表示してその中から必要なアイコンを選択して色も指定しながらpngにすることを検討しました。
SVGファイルをpngに変換する処理で時間がかかりました。この環境は、Webixライブラリを使って構築しているのですが、構築先をインターネットのさくらのインターネット(レンタルサーバ)にしたことで、PHP言語でSVGからpng変換しようとすると、Imagickを使いたかったのですが、Imagickは、php.iniを編集すれば使えるのですが、SVGファイルをPNGに変換するロジックが実装されていないライブラリであることが判明し、PHP言語側での変換をあきらめ、UI(Javascript)側にすることにしました。
まる2日間、思考錯誤してどうにか使える状態になったので、紹介します。

(1)SVGファイルのピックアップ
以下のように2871個のアイコンがあるので、3.9GBの中からSVGファイルだけ取り出す作業が必要でした。かつ、それぞれのファイル名が同じ名称(フォルダ名は異なるけどSVGファイル名は同じ名前)だったので、抽出して、名前を変更後に、1つのフォルダに集める作業が必要です。

このツールはEXCEL(VBA)で作成しました。
以下のようにフォルダを再帰的にスキャンして必要なファイルだけをピックアップし、フォルダ名などをカテゴリ情報として抽出しました。

1つのシンボルに20pxと24pxがある以外にも8種類のファイルがあり、今回は、20pxと24pxだけを使うことにしました。

参考までにVBAソースを紹介します。

'======================================================================
'File Name       : Module1
'Creation Date   : 2024-08-30
'
'Copyright c 2024 sunsunfarm. All rights reserved.
'
'This source code or any portion thereof must not be
'reproduced or used in any manner whatsoever.
'======================================================================

Sub select_source_folder()
    Dim mybookname As String
    Dim menuesheetname As String
    Dim foldername As String
    mybookname = ThisWorkbook.Name
    menuesheetname = "menu"
    foldername = select_foldername()
    If foldername = "" Then
        MsgBox ("操作をキャンセルしましたので、未設定です。")
        Exit Sub
    Else
        Workbooks(mybookname).Worksheets(menuesheetname).Cells(5, 3).Value = foldername
    End If

End Sub

Sub select_copy_folder()
    Dim mybookname As String
    Dim menuesheetname As String
    Dim foldername As String
    mybookname = ThisWorkbook.Name
    menuesheetname = "menu"
    foldername = select_foldername()
    If foldername = "" Then
        MsgBox ("操作をキャンセルしましたので、未設定です。")
        Exit Sub
    Else
        Workbooks(mybookname).Worksheets(menuesheetname).Cells(7, 3).Value = foldername
    End If

End Sub

Sub svg_file_scan_and_workset()
    Dim mybookname As String
    Dim menuesheetname As String
    Dim worksheetname As String
    
    Dim foldername As String
    Dim scan_folder_name As String
    Dim row_pos As Long
    Dim rts As String
    
    mybookname = ThisWorkbook.Name
    menuesheetname = "menu"
    worksheetname = "work"
    
    rts = sheet_clear_exec(2, mybookname, worksheetname, 2, 20000, 1, 4)
    
    scan_folder_name = Workbooks(mybookname).Worksheets(menuesheetname).Cells(5, 3).Value
    row_pos = scan_folder(scan_folder_name, 2)
End Sub


Sub svg_file_rename_and_copy()
    Dim mybookname As String
    Dim menuesheetname As String
    Dim worksheetname As String
    
    Dim foldername As String
    Dim scan_folder_name As String
    Dim copy_foldername As String
    
    Dim row_pos As Long
    Dim rts As String
    Dim i As Long
    Dim cnt As Long
    Dim s_file_name As String
    Dim d_file_name As String
    mybookname = ThisWorkbook.Name
    menuesheetname = "menu"
    worksheetname = "work"
    copy_foldername = Workbooks(mybookname).Worksheets(menuesheetname).Cells(7, 3).Value
    cnt = 1
    For i = 2 To 20000
        foldername = Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 2).Value
        If foldername = "" Then
            Exit Sub
        End If
        d_file_name = Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 4).Value
        If d_file_name <> "" Then
            s_file_name = Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 3).Value
            Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 1).Value = cnt
            'ファイルをcopy
            FileCopy foldername + "\" + s_file_name, copy_foldername + "\" + d_file_name
            cnt = cnt + 1
        End If
    Next
    
End Sub

Sub create_category()
    Dim mybookname As String
    Dim menuesheetname As String
    Dim worksheetname As String
    
    Dim foldername As String
    Dim scan_folder_name As String
    Dim copy_foldername As String
    
    Dim row_pos As Long
    Dim rts As String
    Dim i As Long
    Dim cnt As Long
    Dim s_file_name As String
    Dim d_file_name As String
    Dim str_array As Variant
    mybookname = ThisWorkbook.Name
    menuesheetname = "menu"
    worksheetname = "work"
    copy_foldername = Workbooks(mybookname).Worksheets(menuesheetname).Cells(7, 3).Value
    cnt = 1
    For i = 2 To 20000
        foldername = Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 2).Value
        If foldername = "" Then
            Exit Sub
        End If
        d_file_name = Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 4).Value
        If d_file_name <> "" Then
            str_array = Split(foldername, "\")
            
            Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 5).Value = str_array(3)
            Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 6).Value = str_array(4)
            s_file_name = Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 3).Value
            str_array = Split(s_file_name, ".")
            Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 7).Value = str_array(0)
        End If
    Next
    
End Sub


Function scan_folder(Path As String, row_pos As Long) As Long
    Dim mybookname As String
    Dim menuesheetname As String
    Dim worksheetname As String
    Dim buf As String, f As Object
    Dim set_row_pos As Long
    mybookname = ThisWorkbook.Name
    worksheetname = "work"
    set_row_pos = row_pos
    buf = Dir(Path & "\*.*")
    Do While buf <> ""
        Workbooks(mybookname).Worksheets(worksheetname).Cells(set_row_pos, 2).Value = Path
        Workbooks(mybookname).Worksheets(worksheetname).Cells(set_row_pos, 3).Value = buf
        Workbooks(mybookname).Worksheets(worksheetname).Cells(set_row_pos, 4).Value = get_target_filename(Path, buf)
        set_row_pos = set_row_pos + 1
        buf = Dir()
    Loop
    With CreateObject("Scripting.FileSystemObject")
        For Each f In .GetFolder(Path).SubFolders
            set_row_pos = scan_folder(f.Path, set_row_pos)
        Next f
    End With
     scan_folder = set_row_pos
End Function



Function select_foldername() As String
    Dim MyFolder As String
    On Error GoTo ErrorTrap

    MyFolder = ""
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Show
        MyFolder = .SelectedItems(1)
    End With
 
    select_foldername = MyFolder
    Exit Function
ErrorTrap:
    select_foldername = ""
End Function

Function get_target_filename(pathname As String, file_name As String) As String
    Dim str_array As Variant
    str_array = Split(pathname, "\")
    If str_array(5) = "materialicons" Then
        get_target_filename = str_array(3) + "_" + str_array(4) + "_" + file_name
    Else
        get_target_filename = ""
    End If
End Function

Sub create_insert_sql()
    Dim mybookname As String
    Dim menuesheetname As String
    Dim worksheetname As String
    Dim sql_sheetname As String
    Dim filename As String
    
    Dim i As Long
    Dim sql_str As String
    Dim str1 As String
    Dim rts As String
    Dim row_pos As Long
    Dim category1 As String
    Dim category2 As String
    Dim px As String
    Dim date_info As String
    
    
    mybookname = ThisWorkbook.Name
    worksheetname = "work"
    sql_sheetname = "sql"
    date_info = "2024/08/30 15:45:00"
    rts = sheet_clear_exec(2, mybookname, sql_sheetname, 2, 20000, 1, 4)
    row_pos = 2
    For i = 2 To 20000
        str1 = Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 2).Value
        If str1 = "" Then
            Exit For
        End If
        filename = Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 4).Value
        If filename <> "" Then
            Workbooks(mybookname).Worksheets(sql_sheetname).Cells(row_pos, 1).Value = row_pos - 1
            Workbooks(mybookname).Worksheets(sql_sheetname).Cells(row_pos, 2).Value = filename
            sql_str = "INSERT svgs(filename, category1, category2, px, created_userid, updated_userid, created_on, updated_on) VALUES ("
            sql_str = sql_str + "'" + filename + "',"
            category1 = Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 5).Value
            category2 = Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 6).Value
            px = Workbooks(mybookname).Worksheets(worksheetname).Cells(i, 7).Value
            sql_str = sql_str + "'" + category1 + "',"
            sql_str = sql_str + "'" + category2 + "',"
            sql_str = sql_str + "'" + px + "',"
            sql_str = sql_str + "'admin',"
            sql_str = sql_str + "'admin',"
            sql_str = sql_str + "'" + date_info + "',"
            sql_str = sql_str + "'" + date_info + "');"
           
            
            
            Workbooks(mybookname).Worksheets(sql_sheetname).Cells(row_pos, 3).Value = sql_str
            
            row_pos = row_pos + 1
            
        End If
    Next

End Sub

3つのボタンで作業を実施し、最終的には管理用のDBに格納するINSERT文もVBAで作成しました。


ちょっとした作業を簡単に短時間で実施するには、EXCEL VBAはいいですね。
処理時間もある程度早いし、以下のように1つのフォルダにSVGファイルを名前を変更して集約できました。

SVGファイルは、Webサーバに転送し、同時に作成したINSERT用のSQL文もWebサーバ上で実行してSVGファイルの一覧にしました。
テーブルは、以下のような構成です。

CREATE TABLE 'svgs' (
  'id' int(11) NOT NULL,
  'filename' varchar(255) NOT NULL,
  'category1' varchar(255) NOT NULL,
  'category2' varchar(255) NOT NULL,
  'px' varchar(255) NOT NULL,
  'created_userid' varchar(16) NOT NULL DEFAULT 'admin',
  'updated_userid' varchar(16) NOT NULL DEFAULT 'admin',
  'created_on' datetime DEFAULT NULL,
  'updated_on' datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SVGファイル名とカテゴリ1,2とサイズを持った一覧です。
このデータをwebixを使った画面で一覧表示します。
検索条件にカテゴリ1と2で絞る機能も実装しています。(ファイル名での絞り込みも、PHP側は実装していますが、UIは省略しています)

画面のイメージです。
例は、カテゴリ2でinfo文字を含むアイコンを表示しています。

SVGファイルを一覧表示の列に表示するためにtemplateを使って定義しています

columns:[
	{ id:"id"       ,header:"id", css:{"text-align":"right"},width:60},
	{ id:"icon_id"  ,header:"id", width:50, css:{"text-align":"right"},hidden:true},
	{ id:"filename" ,header:["ファイル名", { content:"textFilter"}] ,  width:270,editor:"text"},
	{ id:"image"    ,header:"アイコン",  template:function(obj){
		  return "<img src='<?php  echo SUB_FOLDER; ?>/image/svg/"+obj.filename+"'>";
		},width:100},
	{ id:"category1",header:["分類1",  { content:"selectFilter"}],  width:200,editor:"text"},
	{ id:"category2",header:["分類2",  { content:"selectFilter"}],  width:200,editor:"text"},
	{ id:"px"       ,header:["サイズ", { content:"selectFilter"}],  width:100,editor:"text"},
],

一覧画面を表示するためのJavascriptソースです。(一部はカットしています)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title><?php echo $TITLE_INFO.' ('.$VER_INFO.')' ?></title>
		<script src="/webix_GPL_1020/webix.js" type="text/javascript" charset="utf-8"></script>
		<link href="/webix_GPL_1020/skins/compact.css?<?php echo date('Ymd-H'); ?>" rel="stylesheet" type="text/css">    
		<link href="<?php  echo SUB_FOLDER; ?>/commonlib/webix_custom_css.css?<?php echo date('Ymd-H'); ?>" rel="stylesheet" type="text/css">    
		<link rel="icon" href="<?php  echo SUB_FOLDER; ?>/image/webix_64.ico">
		<script src="//cdn.webix.com/components/edge/paper/paper.js"></script>
		<script src="<?php  echo SUB_FOLDER; ?>/commonlib/object-assign.js"></script>
		<script src="<?php  echo SUB_FOLDER; ?>/commonlib/moment-with-locales.js"></script>
    	<script src="<?php  echo SUB_FOLDER; ?>/commonlib/webix_common_lib.js"></script>
	<link rel="stylesheet" href="/webix_GPL_1020/css/materialdesignicons.min.css" type="text/css" charset="utf-8">
	<style>
	
  	</style>
	</head>
	<body>
	<script type="text/javascript" charset="utf-8">
		webix.i18n.setLocale("ja-JP");
		var my_local_session = webix.storage.local.get('login');
<?php
	include('../../commonlib/CM0010_goto_menu_action.php');
	include('../../commonlib/CM0030_sendprm_set_request.php');	//送信パラメータ準備関数(in:session_info,access_key out:send_prm)
?>		
	function select_icon_lists(){
    	var send_prm = {}; //検索条件を格納するJSON変数を設定
	   	send_prm.userid = my_local_session.userid;     //検索条件としてグループ名を読み出し
	   	var fl_category1 = $$("fl_category1").getValue();
	   	var fl_category2 = $$("fl_category2").getValue();
	   	if(fl_category1 != ""){
	   		send_prm.fl_category1 = fl_category1;
	   	}
	   	if(fl_category2 != ""){
	   		send_prm.fl_category2 = fl_category2;
	   	}
	   	//DB検索(
	   	webix.ajax("<?php  echo SUB_FOLDER; ?>/rest_api/SV0010/SV0011_svgs_db_selectlists.php",send_prm).then(function(data){
	   		var resp1 = data;
	   		var resp =  data.json();
			if(resp.resp =="ok"){
		   		$$("table").parse(resp.var_lists); 
			}
		});
	}


	webix.ready(function(){
	grida = webix.ui({
  		rows:[
    		{   margin:3,
    			width:800,
      			cols:[
      				{ view:"text",label:"カテゴリ1",id:"fl_category1",name:"fl_category1",width:240},
      				{ view:"text",label:"カテゴリ2",id:"fl_category2",name:"fl_category2",width:240},
 					{ view:"button", id:"search_btn",value: "検索", align:"center", width: 100,
						click:function(){
				    		$$("table").clearAll(); //一覧を一度クリア
							select_icon_lists();
      					}
    				},
      				{ template:""},
      				{ view:"label",label:"",width:30},
					{ view:"button", value: "メニュー", align:"center", width: 100, css:"menu",
						click:function(){
							Goto_Menu();
      					}
    				}
				]
    		},
    		{ view:"datatable",	
      			id:"table",
      			columns:[
        			{ id:"id"       ,header:"id", css:{"text-align":"right"},width:60},
        			{ id:"icon_id"  ,header:"id", width:50, css:{"text-align":"right"},hidden:true},
        			{ id:"filename" ,header:["ファイル名", { content:"textFilter"}] ,  width:270,editor:"text"},
		   			{ id:"image"    ,header:"アイコン",  template:function(obj){
      					  return "<img src='<?php  echo SUB_FOLDER; ?>/image/svg/"+obj.filename+"'>";
    					},width:100},
        			{ id:"category1",header:["分類1",  { content:"selectFilter"}],  width:200,editor:"text"},
        			{ id:"category2",header:["分類2",  { content:"selectFilter"}],  width:200,editor:"text"},
        			{ id:"px"       ,header:["サイズ", { content:"selectFilter"}],  width:100,editor:"text"},
    			],
       			data:[],
      			datatype:"json",
      			height:800,
      			width:525,
      			select:"row",
      			on:{
     				onItemClick:function(row, e, node){
     					var record = $$("table").getItem(row);
     					$$("icon_id").setValue(record.icon_id);
     					$$("filename").setValue(record.filename);
     					$$("px").setValue(record.px);
     					
     					$$("image").setValues({"path":"<?php  echo SUB_FOLDER; ?>/image/svg/","img":record.filename,"width":"120","height":"120"});
     					SV0012_disp_win_show();
     					
     				},
    			}
    		},
  		]
	});
	$$("fl_category1").attachEvent("onEnter",function(ev){
    	$$("search_btn").focus();
    });
	$$("fl_category2").attachEvent("onEnter",function(ev){
    	$$("search_btn").focus();
    });
	
	$$("table").attachEvent("onCheck", function(row, column, state){
  		var record = $$("table").getItem(row);
	});
	});


サーバ側(PHP)側は、DBを検索するのですが、以下のようなソースです。

 <?php
 	//SV0011_svgs_db_selectlists.php
	header("Content-Type: text/javascript; charset=utf-8");
	$myfilename = basename(__FILE__);	//自分自身のファイル名取得
 	$logheader = 'log:'.$myfilename.':';//ログ出力時のヘッダー情報(自ファイル名を付与)
	if($_SERVER["REQUEST_METHOD"] != "GET"){
	  //GET以外ははじく
	  error_log($logheader.'  REQUEST_METHOD no GET');
	  header("HTTP/1.0 404 Not Found");
	  return;
	}
    //検索条件用パラメータ(初期値)
    $userid='';
    $fl_category1 ='';
    $fl_category2 ='';
    $fl_filename ='';
    
    //GET情報からパラメータ取得
    //******** パラメータを正しく修正 ********
	
	if(isset($_GET['userid'])){
		$userid = $_GET['userid'];
	}
	if(isset($_GET['fl_category1'])){
		$fl_category1  = $_GET['fl_category1'];
	}
	if(isset($_GET['fl_category2'])){
		$fl_category2  = $_GET['fl_category2'];
	}
	if(isset($_GET['fl_filename'])){
		$fl_filename  = $_GET['fl_filename'];
	}
	
	error_log($logheader.'   $userid ='.$userid);
	error_log($logheader.'   $fl_category1 ='.$fl_category1);
	error_log($logheader.'   $fl_category2 ='.$fl_category2);
	error_log($logheader.'   $fl_filename  ='.$fl_filename);
    //
    //メインルーチン
    //

    include('../../commonlib/svr_common_lib_v2.php');
    $config_obj = get_config_obj();
    //データベース接続する(MariaDB)
    $dbh = mariadb_connect($config_obj,'app01','webix-server_redmine001');
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    //SQL文を作成して$select_sqlに代入
	$select_sql = 'SELECT id AS icon_id,filename,category1,category2,px FROM svgs ';
	$where_str_array_A = array();

	if($fl_category1 != '' || $fl_category2 != '' || $fl_filename!= '' ){
		if($fl_category1 != ''){
			$where_str_array_A[] =' category1 like "%'.$fl_category1 .'%"';
		}
		if($fl_category2 != ''){
			$where_str_array_A[] =' category2 like "%'.$fl_category2 .'%"';
		}
		if($fl_filename != ''){
			$where_str_array_A[] =' filename like "%'.$fl_filename .'%"';
		}
		$where_str_A = implode(" and ",$where_str_array_A);
		$select_sql =  $select_sql." where ".$where_str_A;
	}

	$select_sql =  $select_sql.' order by filename';
	
	//検索用のSQL文作成(パラメータの状態によって条件を変更)
	//作成したSQL文をログに出力
	error_log($logheader.'  sql='.$select_sql); 
	try {
		//SQL文の実行
		$stmt = $dbh->query($select_sql );
		$var_lists =  $stmt->fetchAll(PDO::FETCH_ASSOC);  //フィールド名だけで保存(index情報なし)
		$count = count($var_lists);
		error_log($logheader.'  $count='.$count); 
		
		for($i=0;$i<$count;$i++){
			$var_lists[$i]["id"] = $i+1;
		}
		$resp = "ok";
		$error_code = 0;
	}catch (Exception $e) {
		error_log($logheader.'  捕捉した例外: '.$e->getMessage());	//例外発生時の処理(エラー情報をログに格納してエラー応答)
		$resp = "ng";
		$count = 0;
	}
   	//後処理
	$stmt = null; 
	$dbh = null;	//DBクローズ
	$json_data = json_encode(compact("resp","error_code","count","var_lists"),JSON_UNESCAPED_UNICODE);
	echo $json_data;
?>

画面からの検索条件をSELECT文に反映させ、DBを検索した結果をJSON形式で応答するロジックです。

Javascript側は受け取ったJSONデータを一覧表に格納することで、画像も含め表示できます。
検索ボタン押下時のUI側のソースです。
検索パラメータを準備して、サーバのPHPをAJAXでコールし、結果をテーブルに格納する操作で完了です。簡単なコードで一覧表ができます。

	function select_icon_lists(){
    	var send_prm = {}; //検索条件を格納するJSON変数を設定
	   	send_prm.userid = my_local_session.userid;     //検索条件としてグループ名を読み出し
	   	var fl_category1 = $$("fl_category1").getValue();
	   	var fl_category2 = $$("fl_category2").getValue();
	   	if(fl_category1 != ""){
	   		send_prm.fl_category1 = fl_category1;
	   	}
	   	if(fl_category2 != ""){
	   		send_prm.fl_category2 = fl_category2;
	   	}
	   	//DB検索(
	   	webix.ajax("<?php  echo SUB_FOLDER; ?>/rest_api/SV0010/SV0011_svgs_db_selectlists.php",send_prm).then(function(data){
	   		var resp1 = data;
	   		var resp =  data.json();
			if(resp.resp =="ok"){
		   		$$("table").parse(resp.var_lists); 
			}
		});
	}

一覧表から1行をクリックすると、明細画面を表示し、その画面上で色を指定して、PNGファイルを作成するボタンクリックすると、PC側に作成したPNGファイルをダウンロードできます。

アイコンのサイズは20px、24pxと小さいので、100pxに拡大したイメージを表示し、色指定をクリックして色を決めます。


colorpickerというコンポーネントで色を指定します。(簡単です)
色を指定したタイミングで、作成するPNGファイル名を決めます。カラーコードを付与したファイル名にします。
色を指定すると、色を変更したSVGファイルを表示します。(実サイズなので、小さいですが)
緑色にした例です。

その後、PNGダウンロードをクリックすると、自動的にPNG
ファイルをダウンロードできます。

透過タイプなので背景が黒ですが、実際には透明です。

EXCELに貼り付けた例です。

セルに記載したabcがみえます。
画面(Javascript)のロジックですが、いろいろ調査をして今回は、以下のようなロジックにしました。SVGファイルは、webix画面に表示したいので、paper.jsを導入して、SVGファイルをインポートする機能で描画し、その画像をPNGに変更してダウンロード操作をしています。
また、SVGファイルには、色が黒なので、色指定を追加(FILLをソースに追加)しています。
画像だけ表示するには、サーバ上のSVGファイルをtemplateを使って指定すれば描画されますが、paper.jsを使ってcanvasに描画するには、SVGのソースでインポートする処理になることや色も変更するため、AJAXメソッドでSVGファイルを指定してソースをUIで受信するロジックにしました。

function disp_svg_image(){
	$$("svg_info").setValue("");
    var access_key = Get_AccessKey();
    var send_prm = Prepare_send_prm(my_local_session,access_key);
    var svg = $$("filename").getValue();
	var xhr =webix.ajax().sync().get("<?php  echo SUB_FOLDER; ?>/image/svg/"+svg,send_prm);
	var svg_file = xhr.responseText;
	if(svg_file != ""){
		var color_code = $$("color").getValue();
		var px = $$("px").getValue();
		if(px == "20px"){
			var svg_file2 = svg_file.replace( 'viewBox="0 0 20 20"', 'viewBox="0 0 20 20" fill="'+color_code+'" ');
		}
		else{
			var svg_file2 = svg_file.replace( 'viewBox="0 0 24 24"', 'viewBox="0 0 24 24" fill="'+color_code+'" ');
		}
		if(paper){
		}
		else{
			paper.setup('canvasA');
    	}
    	with (paper) {
    		var pj =projects;
    		for(var i =0;i<projects.length;i++){
    			if(projects[i]._view._element.id == 'canvasA'){
    				projects[i].clear();
    				projects[i].importSVG(svg_file2, function(item) {
               			//console.log(item);
           			});
    			}
    		}
   		}
   		$$("svg_info").setValue(svg_file2);
	}

}

PNGファイルのダウンロードは、以下のようなイメージです。

var png_filename =$$("create_img_filename").getValue();
const svgData = $$("svg_info").getValue();
if(svgData != "" && png_filename != ""){
	// Canvas要素を作成
	const canvas = document.createElement('canvas');
	const context = canvas.getContext('2d');

	// 高解像度設定
	var px = $$("px").getValue();
	var width = 24; // ダウンロード時の幅
	var height = 24; // ダウンロード時の高さ
	if(px == "24px"){
	}
	else{
		width = 20; // ダウンロード時の幅
		height = 20; // ダウンロード時の高さ
	}
	canvas.width = width;
	canvas.height = height;

	// SVGデータを元に画像を作成
	const img = new Image();

	img.src = 'data:image/svg+xml;charset=utf-8;base64,' + btoa(unescape(encodeURIComponent(svgData))); 

	img.onload = function () {
		// Canvasに描画
		context.drawImage(img, 0, 0, width, height);

		// PNGデータURLを取得
		const pngDataUrl = canvas.toDataURL('image/png');

		// ダウンロードリンクを作成してクリック
		const downloadLink = document.createElement('a');
		downloadLink.href = pngDataUrl;
		downloadLink.download = png_filename;
		downloadLink.click();
	};
}
else{
	webix.alert("SVG情報が存在しません。");
	return;
}

paper.jsの使い方は、Webixのドキュメントやpaper.jsのドキュメントを見る必要があります。
手書きサインや電子印の作成などでもpaper.jsを使っています。

詳しい内容や実際に実装してみたい場合は、ココナラで注文を受けています。そちらも参考にしてください。

次回は、Googleマップへの応用について紹介します。

この記事が気に入ったらサポートをしてみませんか?