Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement base system of the NG image hash #1396

Merged
merged 8 commits into from
May 18, 2024

Conversation

ma8ma
Copy link
Collaborator

@ma8ma ma8ma commented May 18, 2024

画像のハッシュ値を計算して類似する画像をあぼ〜んする機能を実装します。

関連のissue: #1388

ConfigItems: Implement config for image hash initial threshold

NG 画像ハッシュの初期設定のしきい値を記憶する設定と値の取得・設定するインターフェース関数を実装します。
初期設定のデフォルト値は 30 です。

しきい値の取る範囲は 0 が最小(すべてのビットが一致する=同一画像の判定)、128 が最大(すべてのビットが一致しない)となります。
また、マイナスの値は判定を行わない設定に使用します。

ConfigItems: Implement boolean flag config for enabling image hash

NG 画像ハッシュが有効か否かを表す真偽値(有効・無効)の設定を実装します。
有効にすると、画像のハッシュ値を計算してNG 画像ハッシュとの差がしきい値以下の画像をあぼ〜んします。
また、値の取得・設定するインターフェース関数を実装します。
設定のデフォルト値は無効です。

Implement MISC::convert_to_grayscale()

GdkPixbufの画像データをグレイスケール(白黒)画像に変換する関数を実装します。

Implement base system of NG image hash

画像データクラス(DBIMG::Img)に画像のハッシュ値(dHash)を記憶するメンバー変数を追加します。
また、ハッシュ値の取得・設定を行う処理やキャッシュ情報ファイルの保存・読み込みを行う処理を実装します。

画像データベースのルートクラス(DBIMG::ImgRoot)にあぼーんした画像のハッシュ値(NG 画像ハッシュ)を記憶するメンバー変数を追加します。
また、以下の処理を実装しインターフェース関数を作成します。

  • NG 画像ハッシュのリストを取得する
  • 画像データベースにNG 画像ハッシュを登録、更新する
  • NG 画像ハッシュの設定ファイルを保存・読み込む
  • 画像のハッシュ値がNG 画像ハッシュとマッチするかテストする
    • NGのしきい値がマイナスの値ならテストしない
    • ハミング距離がしきい値以下のときはあぼーんする
    • あぼーんしたときは最後にマッチした日時を現在時刻に更新する
    • 画像のキャッシュが保護されているときはテストしない
  • 画像データからハッシュ値を計算する
  • 2つのハッシュ値からハミング距離を計算する

背景事情

修正前でも画像URLを右クリックしてあぼーんすることができますが、一度表示しないとあぼーんの判別ができません。
また、同じ画像でもURLを変えて書き込まれているパターンだとURLのあぼ〜んでは対応が困難となっています。

そのため、画像の特徴をハッシュ値として計算してNG登録し、その後、登録したハッシュ値と比較を行い判定基準を超えた類似画像をあぼ〜んする機能を追加します。

画像のハッシュ値を求めるアルゴリズム

dHashを利用しています。計算があまり複雑でなく他のアルゴリズムよりハッシュのデータが長いため判定基準のしきい値を大きくして許容範囲を広げても誤判定が増えにくいと判断しました。

ImageAreaBase: Add dHash calculation and abone by NG image hash

画像クラスのベースクラス(IMAGE::ImageAreaBase)に画像のdHash計算とNG 画像ハッシュとマッチするかテストする処理を追加します。

画像のハッシュ値を有効にする設定(CONFIG::get_enable_img_hash())がtrueのときは、画像を読み込んで表示する処理の中でハッシュ値を計算してNG 画像ハッシュとマッチするかテストします。

画像のハッシュ値を計算してNGをチェックする場所、タイミングについて

画像のキャッシュ情報を扱うDBIMG::Imgクラスは画像をダウンロードする機能がありますが、取得したバイナリデータはjpeg、png、gifなど各々の画像形式で圧縮されています。
ハッシュ値の計算を行うにはピクセル単位でアクセスできるフォーマットに変換する必要があるためImgクラスの中でハッシュ値の計算をするとクラスが肥大化します。

GTKで画像を扱うときはGdkPixbufを介して行います。
GdkPixbufはピクセル単位でアクセスするAPIが用意されているため、画像のバイナリデータからGdkPixbufを構築する処理がある画像を表示するクラスの処理の中でハッシュ値の計算を行うことにしました。

GdkPixbufを構築するタイミングは画像を表示する直前なので表示済みの画像はNG 画像ハッシュのチェックが発生しません。
画像をポップアップ表示する、画像を一度閉じて開き直す、JDimを再起動するなどGdkPixbufの構築を起こせばNGのチェックが発動します。

IMAGE::Preferences: Add image hash property

画像のプロパティに画像のハッシュ値を表示するように修正します。
ハッシュ値が計算されていないときは空欄になります。

ハッシュ値に関して以下の操作を行うことができます。

  • NG 画像ハッシュの設定をクリップボードにコピーしたい場合は、コピーボタンをクリックします。
  • 画像をNG 画像ハッシュに追加したい場合は、NG 画像ハッシュに追加するチェックボックスを有効にしてダイアログのOKボタンを押します。

画像の右クリックメニューは項目が多くマウスポインターの移動距離が長くなっているためNG 画像ハッシュに追加する処理はプロパティの中に追加します。

Implement CORE::ImageHashTab to display and modify image hash settings

全体あぼーん設定(対象: スレビュー)のダイアログに「NG 画像ハッシュ」のタブを追加します。
タブにはNG 画像ハッシュの一覧といくつかの設定があります。
ダイアログのOKボタンをクリックするとNG 画像ハッシュの設定が更新されます。

ユーザーインターフェース

  • NG 画像ハッシュを有効にするスイッチ (デフォルト設定はoff)
  • 初期設定のしきい値を設定するためのスピンボタンとリセットボタン
    しきい値の有効範囲は [-1, 128], リセットしたときの値は 30
  • ハッシュ値を操作するためのボタン(削除、しきい値設定、コピー)
    項目の複数選択で一括操作が可能
  • 注意事項を表示するトグルボタン
  • NG 画像ハッシュ一覧を表示するツリービュー
    • ハッシュA、ハッシュB
    • しきい値 (クリックで編集可能、Enterキーで決定)
    • 最後にマッチした日時
    • ハッシュのソースURL
  • ツリービューの列名をクリックすると項目をソートする
    しきい値、最後にマッチした日時、ハッシュのソースURLに対応

現状の実装ではNG 画像ハッシュでテストするときツリービューの上から順番に判定を行います。

ImgRoot: Add default NG settings for image hash

NG 画像ハッシュのデフォルト設定を追加します。

デフォルト設定は設定ファイルが見つからないときに読み込まれます。
設定ファイルを初期状態に戻すときはキャッシュディレクトリの中にある image_abone/dhash_list.txt を削除してからJDimを起動してください。

  • デフォルト設定の最後にマッチした日時は 2000-01-01 09:00:00 JST に設定
  • デフォルト設定の目印としてハッシュのソースURLに U+2699 GEAR を追加

デフォルト設定でNGするのは大量にレスを投稿する荒らしが繰り返し書き込んでいたグロテスク・ゴア・残虐な画像です。

ma8ma added 8 commits May 18, 2024 23:59
NG 画像ハッシュの初期設定のしきい値を記憶する設定と
値の取得・設定するインターフェース関数を実装します。
初期設定のデフォルト値は 30 です。

しきい値の取る範囲は 0 が最小(すべてのビットが一致する=同一画像の判定)、
128 が最大(すべてのビットが一致しない)となります。
また、マイナスの値は判定を行わない設定に使用します。
NG 画像ハッシュが有効か否かを表す真偽値(有効・無効)の設定を実装します。
有効にすると、画像のハッシュ値を計算してNG 画像ハッシュとの差が
しきい値以下の画像をあぼ〜んします。
また、値の取得・設定するインターフェース関数を実装します。
設定のデフォルト値は無効です。
GdkPixbufの画像データをグレイスケール(白黒)画像に変換する関数を
実装します。
画像データクラス(`DBIMG::Img`)に画像のハッシュ値(dHash)を記憶する
メンバー変数を追加します。また、ハッシュ値の取得・設定を行う処理や
キャッシュ情報ファイルの保存・読み込みを行う処理を実装します。

画像データベースのルートクラス(`DBIMG::ImgRoot`)にあぼーんした
画像のハッシュ値(NG 画像ハッシュ)を記憶するメンバー変数を追加します。
また、以下の処理を実装しインターフェース関数を作成します。

- NG 画像ハッシュのリストを取得する
- 画像データベースにNG 画像ハッシュを登録、更新する
- NG 画像ハッシュの設定ファイルを保存・読み込む
- 画像のハッシュ値がNG 画像ハッシュとマッチするかテストする
  - NGのしきい値がマイナスの値ならテストしない
  - ハミング距離がしきい値以下のときはあぼーんする
  - あぼーんしたときは最後にマッチした日時を現在時刻に更新する
  - 画像のキャッシュが保護されているときはテストしない
- 画像データからハッシュ値を計算する
- 2つのハッシュ値からハミング距離を計算する

背景事情
修正前でも画像URLを右クリックしてあぼーんすることができますが、
一度表示しないとあぼーんの判別ができません。 また、同じ画像でも
URLを変えて書き込まれているパターンだとURLのあぼ〜んでは対応が
困難となっています。

そのため、画像の特徴をハッシュ値として計算してNG登録し、その後、
登録したハッシュ値と比較を行い判定基準を超えた類似画像を
あぼ〜んする機能を追加します。

画像のハッシュ値を求めるアルゴリズム
dHashを利用しています。計算があまり複雑でなく他のアルゴリズムより
ハッシュのデータが長いため判定基準のしきい値を大きくして許容範囲を広げても
誤判定が増えにくいと判断しました。
画像クラスのベースクラス(`IMAGE::ImageAreaBase`)に画像のdHash計算と
NG 画像ハッシュとマッチするかテストする処理を追加します。

画像のハッシュ値を有効にする設定(`CONFIG::get_enable_img_hash()`)が
trueのときは、画像を読み込んで表示する処理の中でハッシュ値を計算して
NG 画像ハッシュとマッチするかテストします。

画像のハッシュ値を計算してNGをチェックする場所、タイミングについて

画像のキャッシュ情報を扱う`DBIMG::Img`クラスは画像をダウンロードする
機能がありますが、取得したバイナリデータはjpeg、png、gifなど
各々の画像形式で圧縮されています。ハッシュ値の計算を行うには
ピクセル単位でアクセスできるフォーマットに変換する必要があるため
Imgクラスの中でハッシュ値の計算をするとクラスが肥大化します。

GTKで画像を扱うときはGdkPixbufを介して行います。
GdkPixbufはピクセル単位でアクセスするAPIが用意されているため、
画像のバイナリデータからGdkPixbufを構築する処理がある
画像を表示するクラスの処理の中でハッシュ値の計算を行うことにしました。

GdkPixbufを構築するタイミングは画像を表示する直前なので
表示済みの画像はNG 画像ハッシュのチェックが発生しません。
画像をポップアップ表示する、画像を一度閉じて開き直す、JDimを再起動するなど
GdkPixbufの構築を起こせばNGのチェックが発動します。
画像のプロパティに画像のハッシュ値を表示するように修正します。
ハッシュ値が計算されていないときは空欄になります。

ハッシュ値に関して以下の操作を行うことができます。

- NG 画像ハッシュの設定をクリップボードにコピーしたい場合は、
  コピーボタンをクリックします。
- 画像をNG 画像ハッシュに追加したい場合は、NG 画像ハッシュに
  追加するチェックボックスを有効にしてダイアログのOKボタンを押します。

画像の右クリックメニューは項目が多くマウスポインターの移動距離が長く
なっているためNG 画像ハッシュに追加する処理はプロパティの中に追加します。
全体あぼーん設定(対象: スレビュー)のダイアログに「NG 画像ハッシュ」の
タブを追加します。
タブにはNG 画像ハッシュの一覧といくつかの設定があります。
ダイアログのOKボタンをクリックするとNG 画像ハッシュの設定が更新されます。

ユーザーインターフェース
- NG 画像ハッシュを有効にするスイッチ (デフォルト設定はoff)
- 初期設定のしきい値を設定するためのスピンボタンとリセットボタン
  しきい値の有効範囲は [-1, 128], リセットしたときの値は 30
- ハッシュ値を操作するためのボタン(削除、しきい値設定、コピー)
  項目の複数選択で一括操作が可能
- 注意事項を表示するトグルボタン
- NG 画像ハッシュ一覧を表示するツリービュー
  - ハッシュA、ハッシュB
  - しきい値 (クリックで編集可能、Enterキーで決定)
  - 最後にマッチした日時
  - ハッシュのソースURL
- ツリービューの列名をクリックすると項目をソートする
  しきい値、最後にマッチした日時、ハッシュのソースURLに対応

現状の実装ではNG 画像ハッシュでテストするときツリービューの上から順番に
判定を行います。
NG 画像ハッシュのデフォルト設定を追加します。

デフォルト設定は設定ファイルが見つからないときに読み込まれます。
設定ファイルを初期状態に戻すときはキャッシュディレクトリの中にある
`image_abone/dhash_list.txt` を削除してからJDimを起動してください。

- デフォルト設定の最後にマッチした日時は 2000-01-01 09:00:00 JST に設定
- デフォルト設定の目印としてハッシュのソースURLに U+2699 GEAR を追加

デフォルト設定でNGするのは大量にレスを投稿する荒らしが
繰り返し書き込んでいたグロテスク・ゴア・残虐な画像です。
@ma8ma ma8ma added the feature 機能の追加と削除 label May 18, 2024
@ma8ma ma8ma merged commit 3753e4e into master May 18, 2024
20 checks passed
@ma8ma ma8ma deleted the implement-base-system-of-ng-image-hash branch May 18, 2024 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature 機能の追加と削除
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

1 participant