GIMPとInkscapeで電子印を作る

大手さんでなくとも、「請求書はpdfで」となってきました。印刷してスキャンしてpdfにするのも面倒ですし、第一美しくない。見積や請求書に押す「角印」は自分で作ってもいいようです。画像編集フリーソフト「GIMP」とデザインフリーソフト「Inkscape」で、電子角印を作成します。先刻、協業事業者さんのを作成したので、手順を改めてせいりしました。

GIMPでの操作

「GIMP」では、ハンコが下の文書と透けるよう背景透明化と、背景と赤部の二色にするための編集を行います。赤部が完璧でなくともややおおざっぱでOKです。

1) ハンコを紙に押して、スキャナでスキャンします。300dpi以上がよいでしょう。

2) スキャンすると大体.jpgになります。jpgは、背景を透明にできず、圧縮率によっては色の変わり目の色を補完してしまいます。「GIMP」で開いて、まず「ファイル」メニューの「名前を付けてエクスポート」から、拡張子を手打ちで.pngに変更して、エクスポートします。

3) 変換した.pngを「GIMP」で開きます。ハンコが斜めっていたら、ツールボックスの「回転」でまっすぐにします。

4) ハンコの赤部分の背景を透明にします。ツールボックスの「ファジー選択」を選んで、背景を選択し、編集メニュー「切り取り」を選びます。これは背景のゴミを除去する目的もあります。はじめは「ファジー選択」のオプションボックスの「しきい値」を、50くらいとし、おおざっぱに切り取りしていきます。

5) 細かい背景部は、「しきい値」を10くらいで、「切り取り」していきます。

6) 次ぎに画像全体を、減色していきます。「色」メニューの「ポスタリゼーション」を選びます。「ポスタリゼーションのレベル」が、画像の色数を示します。赤部がキレイに残るギリギリまで、少なくします。

7) 「ファジー選択」で赤部を選択します。赤部が選択範囲に収まるように、「しきい値」を調整します。赤部が分離している部分は、「Shift」キーを押したまま、赤部をマウス選択していきます。

8) 赤部が選択できたら、ツールボックスの「塗りつぶし」で、赤色に塗りつぶします。これで背景透明かと、二色化ができました。

9) 「ファイル」メニューの「上書きエクスポート」で、.pngを保存します。

Inkscapeでの操作

「Inkscape」では、画像の図形化と、ハンコ境界線の微調整を行います。

1)「Inkscape」を起動し、「ファイル」メニューの「開く」から.pngを開きます。オプションダイアログが表示るので「平滑化」のチェックは外しておくのが良いでしょう。

2) ハンコ画像部を選んで、「パス」メニューから「ビットマップのトレース」を選びます。OKを押すと、画像が図形化されます。境界線が自動的になめらかになります。なめらかすぎる場合は、Ctrl+Zで戻して、「Speckles」を変更してOKを押し、いい感じなるまで繰り返します。

3) 図形化ができたら、その下位レイヤーにある元画像は不要なので削除します。

4) ハンコ部を赤で塗りつぶします。

5) ツールボックス「ノードツール」を選びます。これでハンコ境界線を調整します。ここから先は、ハンコっぽいくなるように境界位置をマウスで調整していきます。具体的な調整事項は、漢字の真ん中の空間がまん丸、カナのはらい部がとがりすぎ、点の丸部が丸み、外円と内円が真円になっていないなどです。

6) Word/Execl用を生成するには、「ファイル」メニューの「PNGにエクスポート」で.pngを生成します。Word、Execlの貼付け用となります。GIMPで開いてクリップボードにコピーし、Word/Execlに貼付けます。テストして、背景が透明になっているか確認します。サイズを20x20mmに調整して保存しておくと毎回サイズ調整不要となりGoodです。

7) PDF用を生成するには、「ファイル」メニューの「名前を付けて保存」からPDFを選びます。できたPDFは、Acrobat readerの「ツール」タブの「スタンプ」を選び、スタンプバーの「カスタムスタンプ」から、はんこpdfを選び、スタンプ名を付けて登録します。あとは「スタンプ」から命名したスタンプを呼出します。最大サイズでスタンプが挿入されるので、「ものさし」ツールなどで、20x20mmに調整します。

8) 今後のメンテ用に、svg形式でも保存しておきます。

AWS DynmoDB 件数取得で時間要す

ちょっとマニアックで癖のあるAWS DynmoDB。

テーブルアクセス時には、まず件数を知りたいとこです。SQL文なら以下のような感じ。

SELECT count(*) from テーブル名

DynmoDBで、pythonなら以下のような感じです。

tbl1 = dynamodb.Table("テーブル名") 
resp = tbl1.scan(   Select="COUNT", 
                    ReturnConsumedCapacity='TOTAL' )
count   = resp['Count']   

簡単できたと思いましたが落とし穴が、、、

まず感覚的に、他RBMSのSELECT count(*) に比べなんか重い。2万件程度、テーブルにデータを追加してみたところ、エラーが発生しました。

原因は、読出し一回1MB制限でNGでした。count値だけなら1MBに達しないと解釈していましたが、内部的にデータも取り出してくるようです。query でもscanでも同じ。

件数取得したいだけなのに、以下のようにloopにしないといけません。ザックリ1万件づつ読出し。

isLoop = True
totalCount = 0
lastKey=""

while( isLoop == True ):
    if ( lastKey == "" ):  # First scan
        resp = tbl1.scan(   Select="COUNT", 
                            ReturnConsumedCapacity='TOTAL',
                            Limit=10000 )
    else                   # Second or later scan
        resp = tbl1.scan(   Select="COUNT", 
                            ExclusiveStartKey=lastKey,
                            ReturnConsumedCapacity='TOTAL',
                            Limit=10000 )
    count   = resp['Count']   
    totalCount += count 
    #ラストキーがあれば、続きあり 
    if 'LastEvaluatedKey' in resp :  
        lastKey = resp['LastEvaluatedKey']
    else:                       # 続きなし 
        isLoop = False          # loop終了
 

おまけにLambdaのタイムアウトやメモリの動作設定の不足でよく止まってしまいます。弊方の構築したWEBサイトで最も重い処理になってしまいました。

スマートに件数取得を行うには、管理用のテーブルを用意して、カウント対象のテーブルの件数を記録しておくしかなさそうです。

AWS DynmoDB ScanIndexForward読出しで0件!?

ちょっとマニアックで癖のあるAWS DynmoDB。

時系列のログなどは、降順で読み出したいところです。pythonでは以下のようなコードになるかと思います。ScanIndexForwardを指定します。

tbl1 = dynamodb.Table("テーブル名")
   :
   :
resp = tbl1.query(
          KeyConditionExpression=Key('キー名').eq('キー値'),
          ScanIndexForward=False
       )

しかし実際には、query一回の読出し量1MBの制約があります。1MBオーバのエラー検出をして、再読み込みさせるコードを書くなら、以下のように予め一定件数づつ読出しした方が効率的です。

resp = tbl1.query(
          KeyConditionExpression=Key('キー名').eq('キー値'),
          ScanIndexForward=False,
          Limit=1000
       )

当方では、以下のようにプライマリキーは、時刻を入れていました。

登録時刻(プライマリキー)データ1データ2データ3

こうすると、一番新しい時刻から、1000件が降順で読み出されると考えてしまいます。

しかし実際には、読出し件数は、0となってしまいました!!

どうも「一番古いデータから、降順で1,000件」というリクエストと解釈されるようです。

当方では、以下のように対処しました。

resp = tb1.query(
          KeyConditionExpression=Key('キー名').eq('キー値') & Key('時刻').lt('最新時刻'),
                   Limit=1000,
                   ScanIndexForward=False 
           )

‘最新時刻’は、弊方はデータに登録されている現在を用いましたが、現在時刻でもいけるのか未確認です。記録時刻の最大を求めたい場合は、 他RDBでSQL文ですとMAX関数で一発でもとまりますが、Dynamodbでは全件なめにいきそうな気配です。また1MB問題にひっかかりそうですね。

AWS DynmoDB FilterExpressionの落とし穴

ちょっとマニアックで癖のあるAWS DynmoDB。

FilterExpressionで絞り込み検索することは、多々あるかと思います。

データ一覧を、1ページ内に固定件数で表示する場合は、注意が必要です。

例えば、1ページ=50件とすると、pythonでは以下のようなコードになるかと思います。

tbl1 = dynamodb.Table("テーブル名")
   :
   :
resp = tbl1.query(
          KeyConditionExpression=Key('キー名').eq('キー値'),
          FilterExpression=Attr('フィルタ項目名').eq('フィルタ値'), 
          Limit=50 )

しかしこのままですと、対象データが存在していても、目標の50件が取り出せません。最悪0件という場合もあります。

dynamodbでは、Limitの件数を取り出した後に、FilterExpressionがかかります。

通常のRDBをご存じの方は、そんなバカな! という感じられるかと思います。ちょっとひどいですね。

Fillterして規定件数を、読み出したい場合は、以下のようにqueryをloopさせるしかありません。

reccnt=0

while( reccnt < 50 ):
   resp = tbl1.query(
          KeyConditionExpression=Key('キー名').eq('キー値'),
          FilterExpression=Attr('フィルタ項目名').eq('フィルタ値'), 
          Limit=( 50 - reccnt ) 
   )
   if reccnt == 0 :
       items = resp['Items']
   else:
       items.extend(resp['Items']) #検索集合を結合

   reccnt = len(items)

それならこれでいいと思われるかもしれませんが、queryのcall回数のオーバヘッドが生じます。特に、残り1件で、フィルタ後の件数が0が続くと、何回もループしてしまい、応答遅れが顕著に現れます。

本対策としては、FilterExpressionは使わず、予めキーとしてテーブル設計を行う必要があるようです。

しかし既にデータが蓄積された状態では、途中からキー追加は避けたいところです。

AWS DynmoDBでProvisionedThroughputExceededExceptionをpythonで検出するには?

ちょっとマニアックで癖のあるAWS DynmoDB。

ちょっとアクセス負荷をかけると以下のエラーがでてしまいます。少し間をおいて再操作で解消します。

上記はトラブルシューティング用に、pythonでexcept句で検出した内容を、ブラウザにまんま返してるんですが、これはエンドユーザさんが見てしまうと、ビックリして苦情になってしまいます。

なんとかProvisionedThroughputExceededExceptionを検出したいのですが、except句で、まんまProvisionedThroughputExceededExceptionを書いてみると、実行時エラーになってしまいます。

以下URLをみると、

https://botocore.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/exceptions/ProvisionedThroughputExceededException.html

「boto3.dynamodb.Clients.exceptions.ProvisionedThroughputExceededException」かな?と試してみるとダメです。他WEBのHowTo記事にも情報がない。色々試すと以下の方法でできました。

 client = boto3.client('dynamodb') 
   :
   :
try:
  中略
except client.exceptions.ProvisionedThroughputExceededException as e:
    return {
        'statusCode': 503,
        "headers": {"Content-Type": "text/html"},
        'body':'Server busy'
    }    

これで、WEBページ側で、HTTPステータス:503を判定して、やんわりしたメッセージをだせば、ユーザを驚かすことなく、再操作を促せます。

SH2でPCシュミレータを使ってみる

SH2でもPCシュミレーターを試してみます。IDEは、HEWです。

伝統のSHもものは洗練されているかと思いましたが、マイコン機能のすべてがシュミレートされないようです。

タイマCMT0 の割り込みはシュミレートされました。

AD変換完了割り込みは、シュミレートされないようです。Brekeも効かず、カウンタもUPしません。

画面上のボタンを押して、割込みを呼出す機能を使ってもダメ。

変数と関数の呼出し回数を表示しても、AD変換割込みは発生してないです。

RL78のようになマイコン全体のシュミレーション機能ではないようです。関数の単体テスト用でしょうか? もしくはもっと深い使い方があるのでしょうか?

RL78のPCシュミレータを使ってみる

メーカ在籍時は、テスト基板に困ることはありませんでしたが、ベンダーの立場になるとテスト基板が無い状況も多々です。RL78のPCシュミレータを試してみます。IDEは、e2Studioの方です。

詳細な操作方法は、ルネサスのマニュアルをみていただくとし、概要は以下のようにります。

まずデバックの設定で、「RL78 Simulator」を選択します。

シュミレータGUIより、動作条件を設定していきます。

GUIパネルを作って、パネルエディタからドラックで各GUIを配置。.

信号入力にはボタンを割り当て。

AD入力にはダイヤル割り当て。

信号出力はLEDを割り当て。

これでポート入出力、割込み、デバックができます。

タイマーもシュミレートされます。

UARTは、シリアルウインドウを表示して、送信値は手打ちします。簡単な繰返し送信モードがあります。

しかしシュミレーションの実行時間は、現実の4倍くらいありました。

タイミングチャートもあるので、それで実時間との差を確認する必要があります。

Visual Studioのクラス図はどんな感じ

市販のUMLツールでは、クラス図がコードから生成できるもの、できないもの様々なようです。Javaでないとダメなものもあります。Visual Studioでもクラス図が生成できるようです。利用方法は他WEBページでも多数紹介されています。

生成したい状況は、以下の2とおりでしょう。

  • 自分が作ったものを他者に説明したいとき
  • 他人が作ったものを解析したいとき

具体的に使い物になるのか、開発中のコードをあてがって見てみました。

  1. クラスの継承

白い線が継承です。MFCの階層含めて追えていますね。構造体やenumも出してくれます。

2. クラスの関連

クラス間の呼出しや参照、関連は黒い線です。これも追えてはいますね。

3. クラスの関連

メンバリストを必要に応じて閉じることができ、全体の見渡しもしやすいようです。

なるほど。ままず使えそうですね。

iOSシュミレータリストが表示されないとき

引き続きMAC Book Pro 2015でiOSシュミレータも再確認します。しかし、iOSシュミレータリストにデバイス名が出てきません。2012ではバリバリ表示されていたのですが、、、

Xcode SDKと、xamarin.iOSのバージョンが合っていないとダメなようです。合わせるとデバイスリストがでてきました。

iOSアプリの開発環境を安価に作る6

前回記事はこちら

前回、Xcode 12.4では、最新のiOSとは実機デバッグできないことが分かりました。海外のサイトでは、ある程度ならiOSバージョンを戻せるとの情報がありましたが、iOS Ver.16にしてしまうとにっちもさちも行かないようです。

しかたなく最新のmacOS/Xcodeをインストール可能な「MAC Book Pro 2015 early」を導入しました。小キズがある程度で2.8万円でした。これで一気にすべての問題が解決しました。

まずxcodeで試します。実機が選択可能となり、iPhone側で画面がでました。

しかし最新と思っていた「macOS Monterey」ですが近々で「Ventura」というバージョンがリリースされてしまいました。この「Ventura」の対象から、MAC Book Pro 2015は外れてしまいました。iOS17がリリースされたら、2015では対応できないでしょう。

iOSアプリでは、常に開発環境を最新を保っていく必要があるようですね。

Windows側からのiOSシュミレータおよび実機からのデバッグも再トライしてみました。結果は、

  1. 実施できたが遅くで使い物にならない。ほとんどMAC側で動いているんでしょうね。
  2. Visual Studioは2022の最新でないと、iOS16はサポートしていない。xamarin.iOSのバージョンは以下の通りでした。

総費用としましては、MAC Book Pro 2015=2.8万円、iPhone X=2万円、iPhoneケーブル=千円、計4.9万円でした。これにApple開発者の年会費がかかるのでありましょう。