命令・関数(詳細はモジュール内コメントを参照) | 備考 |
---|---|
画像ファイル操作2号 | |
val = ImgF_GetFormat(Path)
画像ファイルを解析して、そのファイルの記録形式を返します。memfile命令対応。
|
val
0 (不明)
1 (BITMAP)
2 (JPEG)
3 (GIF)
4 (PNG)
|
ImgF_GetPicSize Path, SizeX, SizeY
画像ファイルを解析して、その画像を描画した時の画面サイズを取得します。memfile命令対応。
|
分析可能な形式 BMP,JPG,GIF,PNG |
ImgF_PicloadEx Path, Mode, Option, WinID
GDI+を使用して画像ファイルをロードします。memfile命令対応。
picload命令のすごい版として製作しましたがHSP3.31でpicload命令が強化されましたv^ ^。
この命令では透過GIFやアルファブレンドPNGを、gmode 7で使用できるように画像とマスクに分けてのロードが可能です。
|
|
ImgF_jpgsave Path, Quality
bmpsave命令みたいなものです。GDI+を使用してJPG形式でファイル保存します。品質指定付き。
|
Quality 品質 0 (最低・ボロボロ) 100 (最高・すべすべ) |
画像加工と描画 | |
ImgP_CalcFitSize Res_W, Res_H, PicW, PicH, RectW, RectH
縦横比固定で画像を拡縮する時に指定領域に収まる最大サイズを算出します。
|
|
ImgP_gzoom SizeX, SizeY, TrimWinID, TrimX, TrimY, TrimW, TrimH
画像を変倍コピーするgzoom命令のGDI+版です。少しキレイ(〃▽〃)に拡大できるかもです。
|
|
ImgP_grotate TrimWinID, TrimX, TrimY, Angle, Width, Height
画像を回転コピーするgrotate命令のGDI+版です。確実にキレイ(〃▽〃)に描画できます。
|
|
ImgP_RotateFlip Mode, TrimWinID, TrimX, TrimY, TrimW, TrimH
GDI+を使って画像をひっくり返したり裏返したり直角に倒したりします。
|
Mode
0 ( 0°回転)
1 ( 90°回転)
2 (180°回転)
3 (270°回転)
4 ( 0°回転+左右反転)
5 ( 90°回転+左右反転)
6 (180°回転+左右反転)
7 (270°回転+左右反転)
|
ImgP_FilterPastel Lumin, Width, Height
画面ピクセルの輝度を変化させます。各ピクセルは、まっくろからまっしろの間で濃度が変化します。
ImgP_FilterVivid Lumin, Width, Height
画面ピクセルの輝度を変化させます。各ピクセルは、色を強調するような感じに変化します。
|
Lumin -256〜256 (変化度合) ※ 0 (基準、変化なし) |
ImgP_FilterNega Width, Height
現在の画面に対してカレントカラーとのXOR演算を行います。これによりネガ反転などの効果を得ることができます。
|
|
ImgP_GcopySubAbs DiffWinID, PosX, PosY, Width, Height
ふたつの画像の差をとりその絶対値を視覚的に描画します。簡単に言うと、間違い探しの瞬殺が可能です。
|
|
ImgP_Memsave Res_Bin, Format, Width, Height, Option
GDI+を使用して画面イメージを画像ファイルとして保存しますが、保存先はメモリ(変数)上になります。
|
Format 保存形式
1 (BMP) 2 (JPG) 3 (GIF) 4 (PNG)
|
ImgP_LoopCopy Width, Height, WinID, PosX, PosY, SizeW, SizeH, OffsetX, OffsetY
画像をタイルのように敷き詰めるお任せ命令です。
ImgP_PairCopy Width, Height, WinID1, PosX1, PosY1, WinID2, PosX2, PosY2, OffsetX, OffsetY
ふたつの画像を左右に並べるお任せ命令です。
ImgP_Exchange WinID, PosX, PosY, SizeW, SizeH
ふたつの画像を交換するお任せ命令です。
|
/*======================================================================================================= 画像ファイルにいろいろするモジュール HSP3.22 2010.12.30 新規製作 2011. 1. 4 追加:ImgM_GetSize JPG-$C4処理 12 追加:ImgM_SetImageData (暫定) 16 修正:Jpeg Endマーカー無し対策 製作:ImgF_GdipPicload , ImgM_GdipPicload , ImgM_GdipGzoom 移植:ImgM_CalcFitSize 27 修正:Jpeg MarkerSize不正(NikonD700バグ?)対策 HSP3.3β1 2.16 修正:Jpeg 破損画像 対策 HSP3.22(笑) 4. 7 収穫。 5. 1 修正:ImgM_CalcFitSize 0割り HSP3.3β3 7.12 製作:ImgM_GdipJpgsave HSP3.3RC1(正式でてるのに) 9.15 製作:ImgM_GdipRotateFlip 11. 3 上記モジュール全て破棄(Next Stage へ) 画像ファイル操作モジュール2号 & 画像加工モジュール HSP3.3 2011.11. 3 [製作]ImgF_PicloadEx 12.20 [製作]ImgF_GetPicSize,ImgF_GetFormat,ImgP_CalcFitSize,ImgP_gzoom 2012. 1. 9 [移植](コピペ)ImgF_jpgsave,ImgP_RotateFlip 1.11 体裁、モジュール化 HSP3.4β4 2014. 6. 7 ふたつのモジュールを統合、HDL対応 〜 6.28 [廃止](内部関数)_ImgF_LoadAndSigCheck ⇒ ImgF_GetFormatに統合 [製作](内部関数)(実験機構)ImgM_CreateH , ImgM_CloseH [編集]ImgF_PicloadEx 今さらMode2、やらないって言ってたアルファ取得 [編集]ImgP_gzoom 実験中に放置してたらしいorz [製作]ImgP_Memsave , ImgP_FilterPastel/Vivid/Nega/SubAbs , ImgP_grotate HSP3.4+3.5β1 2015. 4.26 [編集]ImgF_PicloadEx ⇒ hsp3cランタイム対応、実験機構の排除1 28 [制作]ImgP_PairCopy, ImgP_LoopCopy [編集]ImgP_Memsave ⇒ hsp3cランタイム対応、実験機構の排除2 HSP3.4+3.5β1+β2 6.16 [製作]ImgP_Exchange, ImgP_FilterBrush (↑このアプデの仕方は非推奨)[編集]ImgP_FilterNega(マクロ化), ImgP_FilterSubAbs ⇒ ImgP_GcopySubAbs(変更) 9. 8 [廃止]ImgM_CreateH , ImgM_CloseH ⇒ 実験機構の排除3(完了) [編集]ImgF_jpgsave,ImgP_gzoom,ImgP_RotateFlip,ImgP_GcopySubAbs,ImgP_grotate %-------------------------------------------------------------------------------------------------------- %dll ; HDL(HSP Document Library)対応ファイル。commonに放り込むだけで対応します。 和謹製モジュール %port ; DLLやモジュールを別途用意する必要はありませんがWin32APIを使用しますので環境に依存します。 Win %author ; Copyright (C) 2010-2015 衣日和 All rights reserved. 衣日和 %url ; 最新版はこちらから。なんかてきとーWEB Site『略して仮。』 http://www.tvg.ne.jp/menyukko/ %note ; 標準ファイル名 ImageModule2.hsp をインクルードする。 WinXP以降の環境はGDI+を標準装備してます。 ; com を使用します。...使いたくないです、いずれ排除したいです。...排除しました。 %======================================================================================================*/ #ifndef ImageModule2Included ; 多重インクルード対策 #define ImageModule2Included ; ←実は不要だったりする(モジュール名で#ifdefできる) #module ImageModule2 #uselib "gdiplus" ; ◆◆ ハローワールドの中心でふぁっきゅーと叫びたいorz ------------------------------ ; ◆ Gdiplusの基礎 #func GdiplusStartup "GdiplusStartup" var, var, nullptr ; [Rtn Token(LoadHandle?)][OpenPrm Struct][Output Struct] #func GdiplusShutdown "GdiplusShutdown" int ; [Token] ; ◆ ImageとBitmapとその周辺と ; ◇画像ファイルから画像取得 #func GdipLoadImageFromFile "GdipLoadImageFromFile" wstr, var ; 無用[FileName][Rtn Image] #func GdipLoadImageFromStream "GdipLoadImageFromStream" int, var ; [Stream][Rtn Image] ; ストリームから入力することで、メモリ上のバイナリデータからの読み込みもできる ; [Stream]は comobj でもいいんだけど、いろいろ都合が悪い。 ; ◇画像をファイル出力 #func GdipSaveImageToFile "GdipSaveImageToFile" int, wstr, var, var ; [Param]不要なら var より nullptr がいい ; [Image][FileName][DataFormat][Param] #func GdipSaveImageToStream "GdipSaveImageToStream" int, int, var, var ; [stream](変数・メモリ上)に保存 ; [Image][Stream][DataFormat][Param] ; ◇[Bitmap]を製作 #func GdipCreateBitmapFromGdiDib "GdipCreateBitmapFromGdiDib" int, int, var ; from HSP Window ; [BitmapInfo(bmscr.6)][BitmapData(bmscr.5)][Rtn Bitmap] #func GdipCloneBitmapAreaI "GdipCloneBitmapAreaI" int, int, int, int, int, int, var ; from Bitmap ; [x][y][Width][Height][PixelFormat][Bitmap][Rtn NewBitmap] ; ◇描画サイズ取得 #func GdipGetImageWidth "GdipGetImageWidth" int, var ; 横幅[Image][Rtn Width] #func GdipGetImageHeight "GdipGetImageHeight" int, var ; 縦幅[Image][Rtn Height] ; ◇90°回転やミラー反転など #func GdipImageRotateFlip "GdipImageRotateFlip" int, int ; [Image][FlipType] ; [FlipType] ; 0 = RotateNoneFlipNone , Rotate180FlipXY ; 4 = RotateNoneFlipX , Rotate180FlipY ; 1 = Rotate90FlipNone , Rotate270FlipXY ; 5 = Rotate90FlipX , Rotate270FlipY ; 2 = Rotate180FlipNone , RotateNoneFlipXY ; 6 = Rotate180FlipX , RotateNoneFlipY ; 3 = Rotate270FlipNone , Rotate90FlipXY ; 7 = Rotate270FlipX , Rotate90FlipY ; ◇[Image]を破棄する #func GdipDisposeImage "GdipDisposeImage" int ; ◆ ImageAttributesとゆかいな仲間たち #func GdipCreateImageAttributes "GdipCreateImageAttributes" var ; [Rtn ImageAttr] #func GdipDisposeImageAttributes "GdipDisposeImageAttributes" int #func GdipSetImageAttributesColorMatrix "GdipSetImageAttributesColorMatrix" \ int, int, int, var, nullptr, nullptr ; 色マトリ [ImageAttr][ColorAdjustType][TRUE=SetCMat/FALSE=ClearCMat][ColorMat][GrayMat][GrayFlag] ; ◆ Matrixのジャケにさり気なく映り込む黒幕w #func GdipCreateMatrix "GdipCreateMatrix" var ; 作る #func GdipDeleteMatrix "GdipDeleteMatrix" int ; 捨てる #func GdipTranslateMatrix "GdipTranslateMatrix" int, float, float, int ; [Matrix][OffsetX][Y][Order] #func GdipRotateMatrix "GdipRotateMatrix" int, float, int ; [Matrix][angle][Order] ; ◆ Graphicsが行く #func GdipCreateFromHDC "GdipCreateFromHDC" int, var ; hdcからGraphics製造 #func GdipDeleteGraphics "GdipDeleteGraphics" int ; Graphics破棄 #func GdipSetWorldTransform "GdipSetWorldTransform" int, int ; GraphicsにMatrix適用 [Graph][Matr] ; ◆ ImageとGraphicsの描画関係(かなりどろどろ) #func GdipDrawImageI "GdipDrawImageI" int, int, int, int ; [Graphics][Image][x][y] #func GdipDrawImageRectI "GdipDrawImageRectI" int, int, int, int, int, int ; [Graphics][Image][x][y][Width][Height] #func GdipDrawImageRectRectI "GdipDrawImageRectRectI" \ int, int, int, int, int, int, int, int, int, int, int, int, nullptr, nullptr ; GraphicsにImageを転写(拡縮付き) ; [Graphics][Image][Paste x][y][Width][Height][base x][y][Width][Height] ; [UnitPixel][ImageAttributes][Callback][CallbackData] ; ◆ 定数など ; GdipCloneBitmapAreaI [PixelFormat] #const PixelFormatIndexed $00010000 ; Indexes into a palette #const PixelFormatGDI $00020000 ; Is a GDI-supported format #const PixelFormatAlpha $00040000 ; Has an alpha component #const PixelFormatCanonical $00200000 #const PixelFormat8bppIndexed 3|( 8<<8)|PixelFormatGDI|PixelFormatIndexed #const PixelFormat24bppRGB 8|(24<<8)|PixelFormatGDI #const PixelFormat32bppARGB 10|(32<<8)|PixelFormatGDI|PixelFormatAlpha|PixelFormatCanonical ; GdipSetImageAttributesColorMatrix [enum ColorAdjustType] ; ColorAdjustTypeDefault, ColorAdjustTypeBitmap, ColorAdjustTypeBrush, ColorAdjustTypePen, ; ColorAdjustTypeText, ColorAdjustTypeCount, ColorAdjustTypeAny/*Reserved*/ #uselib "kernel32.dll" ; ◆◆ カーネル ----------------------------------------------------------------- #func GlobalAlloc "GlobalAlloc" int, int #func GlobalFree "GlobalFree" int #func GlobalLock "GlobalLock" int #func GlobalUnlock "GlobalUnlock" int #func GlobalSize "GlobalSize" int #define GMEM_MOVEABLE 2 #define GMEM_ZEROINIT 64 #define GMEM_SHARE 8192 #define GHND 66 #uselib "Ole32.dll" ; ◆◆ おぇ --------------------------------------------------------------------- #func CreateStreamOnHGlobal "CreateStreamOnHGlobal" int, int, var ; ◆Create Stream With GlobalMemory ; [GlobalHandle]グローバルメモリのハンドル(0にするとストリームが内部で用意してくれる) ; [DelOnRelease]1にするとストリームの解放時にグローバルメモリも削除してくれる...らしい ; [Rtn hStream] 出来あがったストリームのハンドルを受け取る変数 #func GetHGlobalFromStream "GetHGlobalFromStream" int, var ; ◆[Stream]の持つグローバルメモリを拝借 #func ReleaseStgMedium "ReleaseStgMedium" var ; ◆[Stream]やgdi系いろいろハンドルを解放 ; 参考サイト: むしゃぺらり(http://www.setsuki.com/) -> HSP ページ -> gdiplus_test.hsp #uselib "gdi32.dll" ; ◆◆ gdi ---------------------------------------------------------------------- #func BitBlt "BitBlt" int, int, int, int, int, int, int, int, int #func SelectObject "SelectObject" int, int #func CreateCompatibleBitmap "CreateCompatibleBitmap" int, int, int #func DeleteObject "DeleteObject" int #func CreateCompatibleDC "CreateCompatibleDC" int #func DeleteDC "DeleteDC" int ; BitBltのモード(ラスタオペレーションって実はいっぱいある) #define SRCPAINT $00EE0086 ; コピー元とコピー先のor #define SRCCOPY $00CC0020 ; 単純コピー #define PATINVERT $005A0049 ; ブラシとの排他的論理和 #define DSTINVERT $00550009 ; ネガポジ反転 ; bmscr構造体(32bit) mref bmscr,67(カレ窓) or mref bmscr,96+(昔、上限あったけど?) ; ginfoなどの取得関数がある場合はそちらを使った方が適切。 ; (18)WinID (19)redraw (27/28)描画位置座標 ; (33/34)gmodeのサイズ (35)gmodeのモード (65)gmodeのアルファ ; ハンドルを一括管理する実験は失敗に終わった。gdi+とstream以外は直接管理に戻す。 ; [変数]ImghGdip,ImghStream はそれぞれ 0:ハンドル的なもの 1:呼び出しカウント ←変数別けるべきか? #deffunc ImgM_OpenGdiplus ImghGdip(1) ++ if ImghGdip(1) == 1 { ImghGdip(2) = 1, 0, 0, 0 GdiplusStartup ImghGdip, ImghGdip(2) } return #deffunc ImgM_CloseGdiplus ; onexitをつけるべきか? ImghGdip(1) -- if ImghGdip(1) == 0 : GdiplusShutdown ImghGdip return #deffunc ImgM_CreateStream int h ImghStream(1) ++ ; 未初期化変数対策も兼ねてカウントアップする if ImghStream(1) == 1 { ; 多重してはならない if h == 0 : CreateStreamOnHGlobal 0, 1, ImghStream ; GM指定なし if h != 0 : CreateStreamOnHGlobal h, 0, ImghStream ; GM指定あり } return #deffunc ImgM_ReleaseStream ; onexitをつけるべきか? ImghStream(1) -- if ImghStream(1) == 0 : ReleaseStgMedium ImghStream return ; newcom bb, , -1, stream : delcom bb ; ストリームの破棄はコム化してからそのコムを破棄するという処理。 ; GMを開放したら一緒にストリームも破棄されるっていうのはただの都市伝説orz ; コンパクト版ランタイムではコムが使えないので ●脱コム宣言(笑)● /*======================================================================================================= %index ; 旧 "ImageFileModule" %group 画像関連モジュール(ファイル操作2号) %-------------------------------------------------------------------------------------------------------- %index ImgF_GetFormat 画像ファイル解析(画像フォーマット) %prm (Path) Path [文字]ファイル名(パス) %inst Pathで指定したファイルを分析してその記録形式を返します。またmemfile命令による擬似ファイルにも対応しています。 この関数の戻り値は以下のいずれかです。 0 : 不明なフォーマット 1 : BITMAP 2 : JPEG 3 : GIF 4 : PNG %------------------------------------------------------------------------------------------------------*/ #defcfunc ImgF_GetFormat str n ; この関数は副産物として strsize にファイルサイズを返す ; モジュール内変数の sb にファイルデータ全部を取得する(ImgF_GetPicSizeで使うため) exist n : if strsize < 0 : return 0 ; ファイルないよ sb = "(C)衣日和" : memexpand sb, strsize ; sbにファイルデータを全ロード bload n, sb, strsize if wpeek(sb, 0) == $4D42 : return 1 ; BITMAP $42,$4D = "BM" if wpeek(sb, 0) == $D8FF : return 2 ; JPEG $FF,$D8 = "??" if lpeek(sb, 0) == $38464947 : return 3 ; GIF $47,$49,$46,$38 = "GIF8" if lpeek(sb, 0) == $474E5089 & lpeek(sb, 4) == $0A1A0A0D : return 4 ; PNG $89,$50,$4E,$47,$0D,$0A,$1A,$0A = "?PNG????" return 0 ; それ以外の何か /*------------------------------------------------------------------------------------------------------- %index ImgF_GetPicSize 画像ファイル解析(画像の大きさ) %prm Path, SizeX, SizeY Path [文字]ファイル名(パス) SizeX [変数]画像幅(X)が代入される変数(int) SizeY [変数]画像高(Y)が代入される変数(int) %inst Pathで指定したファイルを分析してその画像をロードした時のイメージサイズを取得します。またmemfile命令による擬似ファイルにも対応しています。 分析可能な形式はBMP,JPG,GIF,PNGのいずれかで、命令実行後のシステム変数statにはファイル形式を示す値が代入されます。 %------------------------------------------------------------------------------------------------------*/ #deffunc ImgF_GetPicSize str n, var x, var y x = 0 : y = 0 ; とりあえずぬるぽ。…じゃなくて0を代入 ib = ImgF_GetFormat(n) ; フォーマットタイプ ib(1) = strsize ; データサイズ if ib == 1 { ; ビットマップフォーマット if lpeek(sb, 14) == 40 : x = lpeek(sb, 18) : y =lpeek(sb, 22) ; Windows形式 } if ib == 2 { ; JPEGフォーマット ib(2) = 2 ; offset repeat if ib(1) <= ib(2) : break ; アプリクラッシャー(破損ファイル)対策 if peek(sb, ib(2)) != $FF { ; Nikonクラッシャー対策 ib(2) ++ ; nicoD700nicoのバグ(?)でアプリが堕ちたょ...回避策 continue ; としてMarkerらしきところまでスキップ } ib(3) = peek(sb, ib(2) + 1) if ib(3) == $D9 : break ; ファイル終了のお知らせ if ib(3) == $C0 | ib(3) == $C2 { ; 目的地発見 (ハフマンのベースラインかプログレッシブのMarker) ib(4) = wpeek(sb, ib(2) + 7), wpeek(sb, ib(2) + 5) ; トラップ発動(高さが先だったorz) x = (ib(4) >> 8 & $00FF) | (ib(4) << 8 & $FF00) y = (ib(5) >> 8 & $00FF) | (ib(5) << 8 & $FF00) break } ib(4) = wpeek(sb, ib(2) + 2) ; それ以外の何かの場合 ib(5) = (ib(4) >> 8 & $00FF) | (ib(4) << 8 & $FF00) ib(2) += ib(5) + 2 loop } if ib == 3 : x = wpeek(sb, 6) : y = wpeek(sb, 8) ; GIFフォーマット if ib == 4 { ; PNGフォーマット if lpeek(sb, 12) == $52444849 { ; $49,$48,$44,$52 = "IHDR" ⇒IHDRヘッダーであってしかるべき ib(2) = lpeek(sb, 16), lpeek(sb, 20) ; ビッグエンディアンだなんてorz... x = (ib(2)>>24&$FF) | (ib(2)>>8&$FF00) | (ib(2)<<8&$FF0000) | (ib(2)<<24&$FF000000) y = (ib(3)>>24&$FF) | (ib(3)>>8&$FF00) | (ib(3)<<8&$FF0000) | (ib(3)<<24&$FF000000) } } return ib /*------------------------------------------------------------------------------------------------------- %index ImgF_PicloadEx 画像ファイルをロード(GDI+) %prm Path, Mode, Option, WinID Path [文字]ファイル名(パス) Mode [定数]画像ロードモード 0 : ウィンドウ初期化(白) 1 : ウィンドウの初期化はしない 2 : ウィンドウ初期化(黒) Option [定数]ビットフラグ %**00 = 0 : 描画先Window標準動作 %**01 = 1 : WinIDをbufferで初期化 %**10 = 2 : WinIDをscreenで初期化 %**11 = 3 : WinIDをbgscrで初期化 %00** = 0 : 透過情報を適用(標準) %01** = 4 : 透過情報は無視する %10** = 8 : 透過情報のみを描画 %11** = 12 : gmode 7 で使える形式 WinID [数値]OptionでWindow初期化指定時に利用 0以上 : 指定IDのウィンドウを初期化 -1以下 : 未使用ウィンドウを初期化 %inst HSP標準のpicload命令をGDI+を使って再現します。ロードできるファイル形式はBMP,JPG,GIF,PNGなどGDI+で読み込める必要があります。またmemfile命令による擬似ファイルにも対応しています。 PathとModeはpicload命令と同等ですがOptionを指定することで拡張ロードを実行できます。 Optionでウィンドウの初期化を指定することで、picload前のひと手間(screenやgsel)を省略可能です。ただしModeが1の時はこの設定は適用されません。 OptionでPNGやGIFファイルの持つ透過ピクセル/アルファブレンドの扱いも指定可能です。 %------------------------------------------------------------------------------------------------------*/ #deffunc ImgF_PicloadEx str s, int f, int m, int w ; 本家がPNGに正式対応したため存在意義なくなった。でもmemfile(png時)の拡張子省けるよ viiV <kanikani exist s : if strsize == -1 : return ib = strsize, 0, 0, 0, 0, 0, 0, 0 ; ファイルサイズ, 画像サイズW, 画像サイズH, hGlobal, hStream, hImage, hGraphics, hImageAttr ImgM_OpenGdiplus GlobalAlloc GMEM_ZEROINIT | GMEM_SHARE, ib : ib(3) = stat ; hGlobal GlobalLock ib(3) ; GMを固定する dupptr bb, stat, ib, 2 ; 固定したGMに変数名を割り当てる bload s, bb, ib, 0 ; その変数にファイルの内容を流し込む GlobalUnlock ib(3) ; 固定解除 ImgM_CreateStream ib(3) ; GMからStreamを作る ImghStream参照 GdipLoadImageFromStream ImghStream,ib(5) ; StreamからImage GdipGetImageWidth ib(5), ib(1) ; image.横 GdipGetImageHeight ib(5), ib(2) ; image.縦 if f == 0 | f == 2 { ; ウィンドウの初期化を伴う if (m & 3) == 0 { ; オプションでのウィンドウ指定は無い mref bb, 67 : ib(8) = bb(17), ginfo_sel } else { ; オプションでのウィンドウ指定が有る ib(8) = m & 3 if w < 0 : ib(9) = ginfo_newid : else : ib(9) = w } if (m & %1100) == %1100 : ib(10) = ib(1) * 2 : else : ib(10) = ib(1) ; 横幅 ; ここまででibは (8)ウィンドウ形状 (9)WindowID (10)Window横幅 if ib(8) == 1 : buffer ib(9), ib(10), ib(2) if ib(8) == 2 : screen ib(9), ib(10), ib(2) if ib(8) == 3 : bgscr ib(9), ib(10), ib(2) if f == 2 : boxf ; モード2の時は黒塗りする } GdipCreateFromHDC hdc, ib(6) ; ウィンドウからグラフィクス if m & %1100 { ; オプションでアルファブレンド処理が指定されている場合 GdipCreateImageAttributes ib(7) ; アトリビュート if m & %0100 { ; アルファブレンドを無視する画像描画 ib( 8) = $3F800000, 0, 0, 0, 0, 0, $3F800000, 0, 0, 0, 0, 0, $3F800000, 0, 0 ib(23) = 0, 0, 0, 0, 0, 0, 0, 0, $3F800000, $3F800000 GdipSetImageAttributesColorMatrix ib(7), 1, 1, ib(8) GdipDrawImageRectRectI ib(6),ib(5),ginfo_cx,ginfo_cy,ib(1),ib(2),0,0,ib(1),ib(2),2,ib(7) } if m & %1000 { ; アルファブレンドマスクの取り出し ib( 8) = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ib(23) = $3F800000, $3F800000, $3F800000, 0, 0, 0, 0, 0, $3F800000, $3F800000 GdipSetImageAttributesColorMatrix ib(7), 1, 1, ib(8) GdipDrawImageRectRectI ib(6),ib(5),ginfo_cx+((m>>2&1)*ib(1)),ginfo_cy,ib(1),ib(2),0,0,ib(1),ib(2),2,ib(7) ; 先にプレーン画像を描画しているときは、その画像の右に描画するようにする。 } GdipDisposeImageAttributes ib(7) ; アトリビュートの破棄 } else { ; オプションにアルファブレンド処理が指定ない場合は普通のコピー GdipDrawImageRectI ib(6), ib(5), ginfo_cx, ginfo_cy, ib(1), ib(2) ; (アルファは適用される) } GdipDeleteGraphics ib(6) ; 事後処理 GdipDisposeImage ib(5) ImgM_ReleaseStream GlobalFree ib(3) ImgM_CloseGdiplus mref bb, 67 : if bb(19) & $FFFF0000 : redraw 1 ; 再描画処理 return /*------------------------------------------------------------------------------------------------------- %index ImgF_jpgsave 画面イメージセーブ.JPG編(GDI+) %prm Path, Quality Path [文字]保存するファイル名(パス) Quality [数値]品質 0:高圧縮(粗い)〜100:低圧縮(きめ細やか) %inst HSP標準のbmpsave命令みたいなものです。GDI+を使用してJPG形式でファイル保存します。品質指定付き。 %href alSaveFile ImgP_Memsave %------------------------------------------------------------------------------------------------------*/ #deffunc ImgF_jpgsave str s, int p ; HSP同梱のGDI+イメージ保存にjpeg圧縮率指定が無いことに対する措置 ib = p,0,$557CF401,$11D31A04,$0000739A,$2EF31EF8,1,$1D5BE4B5,$452DFA4A,$B35DDD9C,$EBE70551,1,4,0 ib(13) = varptr(ib) ; 配列自動確保がされてもいいように確定してから代入 ImgM_OpenGdiplus mref bb, 67 : GdipCreateBitmapFromGdiDib bb(6), bb(5), ib(1) GdipSaveImageToFile ib(1), s, ib(2), ib(6) GdipDisposeImage ib(1) ImgM_CloseGdiplus return /*======================================================================================================= %index ; 旧 "ImagePrintModule" %group 画像関連モジュール(加工描画) %-------------------------------------------------------------------------------------------------------- %index ImgP_CalcFitSize 等倍計算(矩形に収まる画像サイズ) %prm Res_W, Res_H, PicW, PicH, RectW, RectH Res_W, Res_H [変数]結果を受け取る変数(int型) PicW, PicH [数値]元画像の大きさ(横幅、縦幅) RectW, RectH [数値]矩形の大きさ(横幅、縦幅) %inst 縦横比固定で画像を拡縮する時に指定領域に収まる最大サイズを算出します。 %href ImgP_gzoom %index ImgP_gzoom 変倍して画面コピー(GDI+) %prm SizeX, SizeY, TrimWinID, TrimX, TrimY, TrimW, TrimH SizeX, SizeY [数値]貼り付け時の画面サイズ TrimWinID [数値]コピー元のウィンドウID TrimX, TrimY [数値]コピー元の起点座標 TrimW, TrimH [数値]コピー元の切り出しサイズ %inst HSP標準のgzoom命令をGDI+を使用して再現します。標準命令よりも、特に拡大時に画質が良くなるかもしれません。 画像はカレントポジションを左上とした位置にSizeXとSizeYで指定した大きさで描画されます。 TrimXとTrimYは通常左上座標ですが、TrimWやTrimHに負数値を指定することでミラー反転を行うことも可能です。 %href ImgP_CalcFitSize %------------------------------------------------------------------------------------------------------*/ #deffunc ImgP_CalcFitSize var x, var y, int a, int b, int w, int h if a == 0 | b == 0 : x = 0 : y = 0 : return ; 0割り。 ib = w * 10000 / a , h * 10000 / b ; 万分率(笑)‰。 if ib < ib(1) : x = w : y = b * ib / 10000 if ib == ib(1) : x = w : y = h if ib > ib(1) : x = a * ib(1) / 10000 : y = h if x + 1 == w : x = w ; 誤差1pixel if y + 1 == h : y = h return ; この命令で実数使ってないのは昔の名残。 #deffunc ImgP_gzoom int w, int h, int i, int x, int y, int a, int b ib = ginfo_sel, 0, 0 ImgM_OpenGdiplus gsel i : mref bb, 67 : GdipCreateBitmapFromGdiDib bb(6), bb(5), ib(1); コピー元をImageにする gsel ib : GdipCreateFromHDC hdc, ib(2) ; コピー先をGraphicにする GdipDrawImageRectRectI ib(2), ib(1), ginfo_cx, ginfo_cy, w, h, x, y, a, b, 2 ; コピー実行。 GdipDeleteGraphics ib(2) GdipDisposeImage ib(1) ImgM_CloseGdiplus mref bb, 67 : if bb(19) & $FFFF0000 : redraw 1 ; 再描画処理 return /*------------------------------------------------------------------------------------------------------- %index ImgP_RotateFlip 画像の反転や90°回転(GDI+) %prm Mode, TrimWinID, TrimX, TrimY, TrimW, TrimH Mode [定数]回転方法 0 : 何もしない (gcopy状態) 1 : 時計回り 90°回転 2 : 時計回り180°回転 (上下左右反転ともいう) 3 : 時計回り270°回転 4 : 0°回転後、左右反転 (左右反転というまでもない) 5 : 90°回転後、左右反転 6 : 180°回転後、左右反転 (上下反転ともいう) 7 : 270°回転後、左右反転 TrimWinID [数値]コピー元のウィンドウID TrimX, TrimY [数値]コピー元の起点座標 TrimW, TrimH [数値]コピー元の切り出しサイズ %inst 画像をミラー反転や90度回転してコピーします。画像はカレントポジションを左上とした位置に描画されます。 %href ImgP_grotate %------------------------------------------------------------------------------------------------------*/ #deffunc ImgP_RotateFlip int m, int i, int x, int y, int w, int h ib = ginfo_sel, 0, 0, 0 ImgM_OpenGdiplus gsel i mref bb, 67 : GdipCreateBitmapFromGdiDib bb(6), bb(5), ib(1) ; コピー元をImageにする GdipCloneBitmapAreaI x, y, w, h, PixelFormat32bppARGB, ib(1), ib(2) ; トリミングしたImage GdipImageRotateFlip ib(2), m ; 回転実行 gsel ib GdipCreateFromHDC hdc, ib(3) ; 貼り付け先のGraphics GdipDrawImageI ib(3), ib(2), ginfo_cx, ginfo_cy ; 貼り付け実行 GdipDeleteGraphics ib(3) GdipDisposeImage ib(2) GdipDisposeImage ib(1) ImgM_CloseGdiplus mref bb, 67 : if bb(19) & $FFFF0000 : redraw 1 ; 再描画処理 return /*------------------------------------------------------------------------------------------------------- %index ImgP_Memsave 画面イメージセーブto変数(GDI+) %prm Res_Bin, Format, Width, Height, Option Res_Bin [変数]データを受け取る変数(文字列型に変換可能であること) Format [定数]保存形式 1 : BMP 2 : JPG 3 : GIF 4 : PNG Width [数値]横幅 Height [数値]縦幅 Option [数値]JPGの時 : 品質(0〜100) %inst 現在の画面イメージをFormatで指定したファイル形式で保存します。Res_Binで指定した変数が出力先となります。命令実行後、システム変数statに出力されたデータサイズ(byte)が代入されています。 WidthかHeightが0や省略の場合、画面全体が対象となります(画像サイズはウィンドウの初期化サイズです)。WidthとHeightが0以外の場合はカレントポジションから指定の範囲が保存されます。 保存形式が2(JPG)の場合、Optionで品質を指定します。0(高圧縮、粗い)から100(低圧縮、きめ細やか)の整数で指定可能です。省略時は0扱いです。 %href ImgF_jpgsave %------------------------------------------------------------------------------------------------------*/ #deffunc ImgP_Memsave var b, int m, int w, int h, int o, int p ; 変数,形式,幅,高さ,品質,(pixelformat) ib = 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0, 1, 0,0,0,0,0,0,0,0 ; (0)GlobalSize (1)stream (2)image(結果) (3)image(works) (4)hGlobal ; (5)PosX (6)PosY (7)Width (8)Height (9)PixelFormat (10〜13)ImageCodec ; (14)パラメ数(0だと保存に失敗するので1以上、1こも必要ない場合はパラメに無効な値をいれるとか...) ; (15〜18)パラメエンコーダ (19)パラメ要素数? (20)パラメ型 (21)ポインタ(っ!) ; (22〜)パラメエンコーダから繰り返し if w==0 | h==0 : ib(5) = 0,0,ginfo_sx,ginfo_sy :else: ib(5) = ginfo_cx,ginfo_cy,w,h ; トリミング mref bb, 67 if bb(3) : ib(9) = PixelFormat8bppIndexed : else : ib(9) = PixelFormat24bppRGB ; ピクフォマ if p : ib(9) = p ; ピクセルフォーマットを外部から指定する実験 if m == 1 : ib(10) = $557CF400, $11D31A04, $0000739A, $2EF31EF8 ; BMP if m == 2 { ib(22) = o ib(10) = $557CF401, $11D31A04, $0000739A, $2EF31EF8 ; JPG ib(14) = 1 ,$1D5BE4B5, $452DFA4A, $B35DDD9C, $EBE70551, 1, 4, varptr(ib(22)) } if m == 3 : ib(10) = $557CF402, $11D31A04, $0000739A, $2EF31EF8 ; GIF if m == 4 : ib(10) = $557CF406, $11D31A04, $0000739A, $2EF31EF8 ; PNG ImgM_OpenGdiplus GdipCreateBitmapFromGdiDib bb(6), bb(5), ib(3) GdipCloneBitmapAreaI ib(5), ib(6), ib(7), ib(8), ib(9), ib(3), ib(2) ImgM_CreateStream 0 GdipSaveImageToStream ib(2), ImghStream, ib(10), ib(14) ; if stat : ImgM_CloseH : return 0 ; 明らかな不成功とか、マジ消えろ。 ; ↑この安全装置は解除した。。。 GetHGlobalFromStream ImghStream, ib(4) ; ストリーム管理のhGlobalを拝借 GlobalSize ib(4) : ib = stat ; おおきさ b = "(C)衣日和" : memexpand b, ib ; メモリ確保 GlobalLock ib(4) dupptr bb, stat, ib, vartype("str") memcpy b, bb, ib GlobalUnlock ib(4) ImgM_ReleaseStream GdipDisposeImage ib(2) GdipDisposeImage ib(3) ImgM_CloseGdiplus return ib /*------------------------------------------------------------------------------------------------------- %index ImgP_FilterPastel 画像フィルター(輝度補正) %prm Lumin, Width, Height Lumin [数値]補正値(-256〜256) Width [数値]横幅 Height [数値]縦幅 %inst 現在の画面に対して輝度補正を行います。 WidthかHeightが0や省略の場合、画面全体が対象となります。WidthとHeightが0以外の場合はカレントポジションから指定の範囲が対象です。 Luminに輝度変化の割合を指定します。この値によって各ピクセルは、まっくろ(-256指定時)からまっしろ(256指定時)の間で変化します。なお、0を指定した時の輝度変化はありません(基準)。 Luminに正数を指定すると、パステル調の白が混じったようなやわらかい印象になります。 Luminに負数を指定すると、全体的に暗く色変化の乏しい画像になります。 %href ImgP_FilterVivid %index ImgP_FilterVivid 画像フィルター(色強調) %prm Lumin, Width, Height Lumin [数値]補正値(-256〜256) Width [数値]横幅 Height [数値]縦幅 %inst 現在の画面に対して輝度補正を行います。 WidthかHeightが0や省略の場合、画面全体が対象となります。WidthとHeightが0以外の場合はカレントポジションから指定の範囲が対象です。 Luminに輝度変化の割合を指定します。この値によって各ピクセルは色を強調するように変化します。 Luminに正数を指定すると、各ピクセルの色は濃くなります。特に暗い色ほど、より大きく輝度が下がることになります。Lumin=256の時の目安は以下の通りです。 輝度 = 元輝度 - (255 - 元輝度) ※例) 元輝度が250の時、輝度は245 ※例) 元輝度が130の時、輝度は5 Luminに負数を指定すると、各ピクセルの色は白に近づきます。Lumin=-256の時、元の輝度の2倍の輝度に変化します。 Luminに0を指定した時の輝度変化はありません(基準)。 いずれの場合も輝度が0〜255の範囲に収まるように下上限処理されます。 %href ImgP_FilterPastel %------------------------------------------------------------------------------------------------------*/ #deffunc ImgM_FilterLight int l, int w, int h, int m ; 光度?輝度? mref bb, 67 ; ginfoでも結構いけるけど全部これで ib = bb(19), bb(35), bb(33), bb(34), bb(65) ; 再描画フラグとgmodeの現在値 if w == 0 | h == 0 : ib(5) = 0, 0, bb(1), bb(2) : else : ib(5) = bb(27), bb(28), w, h ; 範囲 ib(9) = bb(27), bb(28) ; カレントポジション(忘れてた...) if m == 0 : gmode 5, , , limit(abs(l), 0, 256) ; モード:ビビッドトーン if m == 1 : gmode 6, , , limit(abs(l), 0, 256) ; モード:パステルトーン redraw 0 ; ネガ時のgcopyが一瞬光るので強制的にオフっとく if 0 < l : BitBlt hdc, ib(5), ib(6), ib(7), ib(8), , , , DSTINVERT ; ネガ pos ib(5), ib(6) : gcopy bb(18), ib(5), ib(6), ib(7), ib(8) if 0 < l : BitBlt hdc, ib(5), ib(6), ib(7), ib(8), , , , DSTINVERT ; ポジ pos ib(9),ib(10) : gmode ib(1),ib(2),ib(3),ib(4) ; そして元の位置に戻す if ib & $FFFF0000 : redraw 1 ; 再描画(設定の復元もかねて) return ; 組み合わせて4つの命令ができたけど↑最終的に1こにまとまった(笑 ↓マクロの形で提供 #define global ImgP_FilterPastel(%1,%2=0,%3=0) ImgM_FilterLight %1,%2,%3,1 #define global ImgP_FilterVivid(%1,%2=0,%3=0) ImgM_FilterLight %1,%2,%3,0 ; 補正値が正数だとビビっとあざやかって感じではなくガンマとかコントラストとかが近いかも /*------------------------------------------------------------------------------------------------------- %index ImgP_FilterNega 画像フィルター(ネガポジ、排他的論理和=XOR) %prm Width, Height Width [数値]横幅 Height [数値]縦幅 %inst 現在の画面に対してカレントカラーとのXOR演算を行います。 WidthかHeightが0や省略の場合、画面全体が対象となります。WidthとHeightが0以外の場合はカレントポジションから指定の範囲が対象です。 XORはいわばビット反転をする計算で、たとえば %11001100 ^ %00001111 → %11000011 ※ %11001100:被数 ^:演算子 %00001111:対象ビット指定 となります。 ですので、まっしろ(255, 255, 255)とのXORはネガポジ効果を、まっくろ(0, 0, 0)とのXORは無意味となるほか、さまざまな画像効果を得ることができます。 %------------------------------------------------------------------------------------------------------*/ #deffunc ImgP_FilterBrush int w, int h, int o mref bb, 67 SelectObject hdc, bb(36) : ib = stat ; HSPが作り置きしているブラシオブジェを設定 if w == 0 | h == 0 : ib(1) = 0, 0, bb(1), bb(2) : else : ib(1) = bb(27), bb(28), w, h ; ハニ BitBlt hdc, ib(1), ib(2), ib(3), ib(4), , , , o ; ブラシ はにっ!?→範囲 SelectObject hdc, ib ; 元のブラシに戻す if bb(19) & $FFFF0000 : redraw 1 ; 再描画処理 return #define global ImgP_FilterNega(%1=0,%2=0) ImgP_FilterBrush %1,%2,PATINVERT@ImageModule2 ; ネガポジと言うには性質がやや違う気がするorz /*------------------------------------------------------------------------------------------------------- %index ImgP_GcopySubAbs 画像フィルター(2画像の差の絶対値) %prm DiffWinID, PosX, PosY, Width, Height DiffWinID [数値]画像BのウィンドウID PosX, PosY [数値]画像Bの左上座標 Width, Height [数値]横幅、縦幅 %inst 現在の画面(画像A)とパラメータ指定の画面(画像B)で差をとりその絶対値を示します。この画像は輝度の差が小さいほど暗い(黒い)点として表示され ・良く似た2つの画像の相違点を視覚的に示す ・圧縮による画質の劣化具合の判定 ・色減算コピー時にクランプされている部分の視覚化 といった用途に使用可能です。 画像Aについて、WidthかHeightが0や省略の場合は現在の画面全体が対象となります。WidthとHeightが0以外の場合はカレントポジションから指定の範囲が対象です。 画像Bは指定座標を左上とする位置から画像Aと同サイズが対象となります。結果画像は画像Aを上書きする形で描画されます。 %------------------------------------------------------------------------------------------------------*/ #deffunc ImgP_GcopySubAbs int i, int x, int y, int w, int h ; やっていることは[A-B=C][B-A=D][C+D=E]の画像加減コピーに過ぎないが、作業用Win不要化で回りくどい。 ; 画像ストックのコンパチはコピー元Winに合わせる(コピー元画像(計算後に残る方)の劣化を防ぐため)。 ; [C+D=E]は、負数クランプの為、一方は 0 になっている → 論理和/排他的論理和/合算(加算)どれでもOK! ; ib( 0〜 7)コピー先設定 0:WinID 1:redrawFrag 2-5:gmode 6-7:curPos ; ib( 8〜11)出力位置範囲 8-9:pos 10-11:size ; ib(12〜18)コピー元設定 12:redrawFlag 13-16:gmode 17-18:curPos ; ib(19〜21)ハンドルズ 19:CreateHDC 20:CreatehBitmap 21:hBitmapStock mref bb, 67 ib = bb(18), bb(19), bb(35), bb(33), bb(34), bb(65), bb(27), bb(28) ; コピー先設定(控え) redraw 0 ; コピー先再描画オフ if w == 0 | h == 0 : ib(8) = 0, 0, bb(1), bb(2) :else: ib(8) = bb(27), bb(28), w, h ; 範囲計算 gsel i ; ここからの hdc はコピー元 mref bb, 67 ib(12) = bb(19), bb(35), bb(33), bb(34), bb(65), bb(27), bb(28), 0, 0, 0 ; コピー元控え+hndl域 redraw 0 ; コピー元再描画オフ CreateCompatibleDC hdc : ib(19) = stat ; デバコン作り CreateCompatibleBitmap hdc, ib(10) * 2, ib(11) : ib(20) = stat ; ビトマ作り SelectObject ib(19), ib(20) : ib(21) = stat ; ビトマ差し替え BitBlt ib(19), ib(10), 0, ib(10), ib(11), hdc, x, y, SRCCOPY ; コピー元の画像を控えておく gmode 6, ib(10), ib(11), 256 : pos x, y : gcopy ib, ib(8), ib(9) ; まずコピー元に減算実行 BitBlt ib(19), 0, 0, ib(10), ib(11), hdc, x, y, SRCCOPY ; 減算結果を控える BitBlt hdc, x, y, ib(10), ib(11), ib(19), ib(10), 0, SRCCOPY ; コピー元は減算前に戻す gsel ib ; ここからの hdc はコピー先 gmode 6, ib(10), ib(11), 256 : pos ib(8), ib(9) : gcopy i, x, y ; 次にコピー先に減算実行 BitBlt hdc, ib(8), ib(9), ib(10), ib(11), ib(19), 0, 0, SRCPAINT ; ふたつの減算結果を合体 SelectObject ib(19), ib(21) ; 差し替えていたビトマを差し戻す DeleteObject ib(20) ; ビトマ廃棄 DeleteDC ib(19) ; デバコン廃棄 ; ウィンドウのCurPos/gmode/RedrawFlagを復元(WinID一致の可能性を考慮して最後にまとめて仕上げる) gsel i : pos ib(17),ib(18) : gmode ib(13),ib(14),ib(15),ib(16) : if ib(12)&$FFFF0000 : redraw 1 gsel ib : pos ib( 6), ib(7) : gmode ib( 2),ib( 3),ib( 4),ib( 5) : if ib( 1)&$FFFF0000 : redraw 1 return /*------------------------------------------------------------------------------------------------------- %index ImgP_grotate 矩形画像を回転してコピー(GDI+) %prm TrimWinID, TrimX, TrimY, Angle, Width, Height TrimWinID [数値]元画像のウィンドウID TrimX, TrimY [数値]元画像の起点(左上)座標 Angle [実数]回転角度(ラジアン、1周=2π・時計回り) Width, Height [数値]描画サイズ(横幅、縦幅) %inst HSP標準のgrotate命令をGDI+を使用して再現します。…が異なる点も多いです。標準命令よりも画質が良くなります。 描画はカレントポジションを中心とした位置に行われます。 描画後の矩形サイズをWidthとHeightに指定します。回転するため画像はこの矩形には収まりません。WidthかHeightを0か省略した場合は等倍コピー、大きさを指定した場合は拡大・縮小コピーになります。 元画像のサイズはgmode命令で設定した値を使用しますので、あらかじめ指定しておいてください。 gmodeのコピーモードは0か1のみに対応しています(つまりベタぬりです)。 元画像の範囲に画面外領域が含まれる場合、その領域は透過画素の扱いになります(grotateではリサイズ?されるようで、拡縮・描画位置に影響が出ます)。 %href ImgP_RotateFlip %------------------------------------------------------------------------------------------------------*/ ; grotateの再現と言うより、任意角回転命令としてまとめた方が簡素で良いかも? #deffunc ImgP_grotate int i, int x, int y, double r, int w, int h mref bb, 67 ; この処理って実のところartlet2dにー対ーで対応できる ib = bb(18), bb(19), bb(35), bb(33), bb(34), bb(65), bb(27), bb(28), w, h, 0, 0, 0 if w == 0 | h == 0 : ib(8) = ib(3), ib(4) ; : else : ib(8) = w, h ; 描画サイズ ; ib(0-7)描画先情報 0:WinID 1:redrawFrag 2-5:gmode 6-7:curPos←使ってなくね? ; ib(8-9)貼り付け時の大きさ ちなみにib(3-4)切り取りサイズ ; ib(10-12)ハンドル matrix,graphic,image ImgM_OpenGdiplus GdipCreateMatrix ib(10) ; matrixを作る GdipTranslateMatrix ib(10), ginfo_cx, ginfo_cy, 0 ; 座標は、実は実数 GdipRotateMatrix ib(10), rad2deg(r), 0 ; GDI+ではrad→degする GdipTranslateMatrix ib(10), -ginfo_cx, -ginfo_cy, 0 GdipCreateFromHDC hdc, ib(11) ; 描画先のgraphic GdipSetWorldTransform ib(11), ib(10) gsel i : mref bb, 67 : GdipCreateBitmapFromGdiDib bb(6), bb(5), ib(12) ; 元画像のimage gsel ib GdipDrawImageRectRectI ib(11),ib(12),ginfo_cx-ib(8)/2,ginfo_cy-ib(9)/2,ib(8),ib(9),x,y,ib(3),ib(4),2 GdipDisposeImage ib(12) GdipDeleteGraphics ib(11) GdipDeleteMatrix ib(10) ImgM_CloseGdiplus if ib(1) & $FFFF0000 : redraw 1 return /*------------------------------------------------------------------------------------------------------- %index ImgP_PairCopy 画面コピー(2画像を左右に並べる) %prm Width, Height, WinID1, PosX1, PosY1, WinID2, PosX2, PosY2, OffsetX, OffsetY Width, Height [数値]1画像の横幅と縦幅 WinID1, PosX1, PosY1 [数値]左側画像指定 WinID2, PosX2, PosY2 [数値]右側画像指定 OffsetX, OffsetY [数値]右側画像の位置補正 %inst 現在の画面・座標に対してgmode 0の画面コピー(gcopy)を2回実行するおまとめ命令です。2つの画像は横に隣接するように描画され ・離れた場所にあるgmode 7用の画像とマスクを組み合わせる ・視差(ステレオグラム)を使った演出 といった用途に使えます。 %------------------------------------------------------------------------------------------------------*/ #deffunc ImgP_PairCopy int w, int h, int l, int m, int n, int r, int s, int t, int o, int v mref bb, 67 ; ステレオって立体って意味だった。 ib = bb(35), bb(33), bb(34), bb(65), bb(27), bb(28) ; 設定戻し用(gmodeとpos) if w == 0 | h == 0 : ib(6) = ib(1), ib(2) : else : ib(6) = w, h ; 描画サイズ gmode 0, ib(6), ib(7) pos ib(4) + ib(6) + o, ib(5) + v : gcopy r, s, t pos ib(4), ib(5) : gcopy l, m, n gmode ib, ib(1), ib(2), ib(3) ;: pos ib(4), ib(5) ; 設定戻し return /*------------------------------------------------------------------------------------------------------- %index ImgP_LoopCopy 画面コピー(範囲敷き詰め) %prm Width, Height, WinID, PosX, PosY, SizeW, SizeH, OffsetX, OffsetY Width, Height [数値]敷き詰める範囲 WinID, PosX, PosY, SizeW, SizeH [数値]敷き詰める画像 OffsetX, OffsetY [数値]画像切り出し位置(左上) %inst 現在の画面・座標からWidth/Heightで指定した範囲を埋めるように画像を繰り返しコピーします。gmode命令でコピー方法を指定することが可能です。 %------------------------------------------------------------------------------------------------------*/ #deffunc ImgP_LoopCopy int w, int h, int i, int x, int y, int s, int t, int o, int v mref bb, 67 ib = bb(19), ginfo_cx, ginfo_cy, 0, 0, 0 ; redraw flag, curposx, y, temp hdc, hbitmap, old hbmp if s == 0 | t == 0 : ib(6) = bb(33), bb(34) : else : ib(6) = s, t ; 1チップのサイズ ib(8) = ib(1), ib(2), w, h ; 描画開始位置とサイズ if o : ib(8) -= o : ib(10) += o ; サイズ補正(左側半端域) if v : ib(9) -= v : ib(11) += v ; サイズ補正(上側半端域) if ib(10) \ ib(6) : ib(10) += ib(6) - ib(10) \ ib(6) ; サイズ補正(右側半端域) if ib(11) \ ib(7) : ib(11) += ib(7) - ib(11) \ ib(7) ; サイズ補正(下側半端域) ib(12) = ib(10) / ib(6), ib(11) / ib(7) ; 横縦にチップを敷き詰める枚数 if w != ib(10) | h != ib(11) { ; 前後左右に半端域がある場合(補正で枚数が増えたとき) CreateCompatibleDC hdc : ib(3) = stat CreateCompatibleBitmap hdc, ib(10), ib(11) : ib(4) = stat SelectObject ib(3), ib(4) : ib(5) = stat BitBlt ib(3), 0, 0, ib(10), ib(11), hdc, ib(8), ib(9), SRCCOPY ; 半端部分は一度描画しちゃってから元の絵を貼りなおすという処理にする(gmode 7 対応) } redraw 0 repeat ib(13) ib(14) = cnt * ib(7) + ib(9) repeat ib(12) pos cnt * ib(6) + ib(8), ib(14) : gcopy i, x, y, ib(6), ib(7) loop loop if w != ib(10) | h != ib(11) { ; 半端域戻し ib(14) = ib(8) + ib(10) - ib(1) - w, ib(9) + ib(11) - ib(2) - h ; 右下削り幅 if o : BitBlt hdc, ib(8), ib(9), o, ib(11), ib(3), 0, 0, SRCCOPY if v : BitBlt hdc, ib(8), ib(9), ib(10), v, ib(3), 0, 0, SRCCOPY if ib(14) : BitBlt hdc,ib(8)+ib(10)-ib(14),ib(9),ib(14),ib(11), ib(3),ib(10)-ib(14),0, SRCCOPY if ib(15) : BitBlt hdc,ib(8),ib(9)+ib(11)-ib(15),ib(10),ib(15), ib(3),0,ib(11)-ib(15), SRCCOPY ; このbitbltはブラシやマスクで一発で決められないだろうか SelectObject ib(3), ib(5) : ib(4) = stat ; bitmapを戻す(ib.4の値は変わらないと思われる) DeleteObject ib(4) DeleteDC ib(3) } pos ib(1), ib(2) : if ib & $FFFF0000 : redraw 1 ; 設定戻し込み再描画 return /*------------------------------------------------------------------------------------------------------- %index ImgP_Exchange 画面コピー(2画像を交換) %prm WinID, PosX, PosY, SizeW, SizeH WinID [数値]画像BのウィンドウID PosX, PosY [数値]画像Bの左上座標 SizeW, SizeH [数値]横幅、縦幅 %inst 現在の画面(画像A)とパラメータ指定の画面(画像B)を交換します。 画像Aについて、WidthかHeightが0や省略の場合は現在の画面全体が対象となります。WidthとHeightが0以外の場合はカレントポジションから指定の範囲が対象です。 画像Bは指定座標を左上とする位置から画像Aと同サイズが対象となります。 %------------------------------------------------------------------------------------------------------*/ #deffunc ImgP_Exchange int i, int x, int y, int w, int h ib = ginfo_sel, hdc if w == 0 | h == 0 : ib(2) = 0, 0, ginfo_sx, ginfo_sy : else : ib(2) = ginfo_cx, ginfo_cy, w, h CreateCompatibleDC hdc : ib(6) = stat CreateCompatibleBitmap hdc, ib(4), ib(5) : ib(7) = stat SelectObject ib(6), ib(7) : ib(8) = stat BitBlt ib(6), 0, 0, ib(4), ib(5), hdc, ib(2), ib(3), SRCCOPY gsel i BitBlt ib(1), ib(2), ib(3), ib(4), ib(5), hdc, x, y, SRCCOPY BitBlt hdc, x, y, ib(4), ib(5), ib(6), 0, 0, SRCCOPY ; 領域が重なった場合は画像Aが優先になる SelectObject ib(6), ib(8) DeleteObject ib(7) DeleteDC ib(6) mref bb, 67 : if bb(19) & $FFFF0000 : redraw 1 if i != ib : gsel ib : mref bb, 67 : if bb(19) & $FFFF0000 : redraw 1 return ; http://www.tvg.ne.jp/menyukko/ ; Copyright(C) 2010-2015 衣日和 All rights reserved. #global #endif
screen 0, 800, 600 : title "『略して仮。』http://www.tvg.ne.jp/menyukko/" ; redraw 0 ; ←うちのモジュールは再描画フラグをちゃんとチェックしているはず、、、 pos 4, 4 : mes "@PicloadEx(Opt=1+12)" ; 透過もちPNGを画像/マスク分離ロード ImgF_PicloadEx dir_tv + "hsptv_img.png", 0, 1 + 12, 1 ; 未初期化ウィンドウ強制用意ロード gsel 0 : pos 4, 22 : gcopy 1, 416, 0, 192, 128 pos 204, 4 : mes "AMemsave(BMP)以降の元絵" ; 画面の一部をビットマップ形式で gsel 1 : pos 192, 320 : ImgP_Memsave BinBuf, 1, 192, 128 ; メモリに保存してmemfileで読み込む memfile BinBuf, 0, stat : gsel 0 : pos 204, 22 : picload "MEM:dummy", 1 pos 404, 4 : mes "BMemsave(GIF)" ; GIFの場合は最大256色 pos 204, 22 : ImgP_Memsave BinBuf, 3, 192, 128 memfile BinBuf, 0, stat : pos 404, 22 : picload "MEM:dummy", 1 pos 604, 4 : mes "CMemsave(PNG)+PicloadEx" ; PNGをmemfile+picloadする場合は、 pos 204, 22 : ImgP_Memsave BinBuf, 4, 192, 128 ; 拡張子(.png)が必要になるかもね? memfile BinBuf, 0, stat pos 604, 22 : ImgF_PicloadEx "MEM:dummy", 1 ; ←拡張子は付いてないよ。 pos 4, 154 : mes "DMemsave(JPG Quo=90)" ; JPGは非可逆なので劣化は免れない。 pos 204, 22 : ImgP_Memsave BinBuf, 2, 192, 128, 90 memfile BinBuf, 0, stat : pos 4, 172 : picload "MEM:dummy", 1 pos 204, 154 : mes "EMemsave(JPG Quo=10)" ; JPG超圧縮。画質は… pos 204, 22 : ImgP_Memsave BinBuf, 2, 192, 128, 10 memfile BinBuf, 0, stat : pos 204, 172 : picload "MEM:dummy", 1 pos 404, 154 : mes "FSubAbs D&E" ; 圧縮率による画像の劣化具合を見てみよう pos 404, 172 : gcopy 0, 4, 172, 192, 128 : ImgP_GcopySubAbs 0, 204, 172, 192, 128 pos 604, 154 : mes "GVivid F×8" ; 劣化具合を強調してみる pos 604, 172 : gcopy 0, 404, 172, 192, 128 ImgP_FilterVivid -256, 192, 128 ; 2倍 ImgP_FilterVivid -256, 192, 128 ; 2倍の2倍 → つまり4倍 ImgP_FilterVivid -256, 192, 128 ; つまり4倍の2倍 → 8倍 pos 4, 304 : mes "HPastel(Lum=128)" ; パステルフィルタとビビッドフィルタ pos 4, 322 : gcopy 0, 204, 22, 192, 128 : ImgP_FilterPastel 128, 192, 128 pos 204, 304 : mes "IPastel(Lum=-128)" pos 204, 322 : gcopy 0, 204, 22, 192, 128 : ImgP_FilterPastel -128, 192, 128 pos 404, 304 : mes "JVivid(Lum=128)" pos 404, 322 : gcopy 0, 204, 22, 192, 128 : ImgP_FilterVivid 128, 192, 128 pos 604, 304 : mes "KVivid(Lum=-128)" pos 604, 322 : gcopy 0, 204, 22, 192, 128 : ImgP_FilterVivid -128, 192, 128 pos 4, 454 : mes "LNega(255,255,255)" ; ネガポジる color 255, 255, 255 pos 4, 472 : gcopy 0, 204, 22, 192, 128 : ImgP_FilterNega 192, 128 color 0, 0, 0 ; 色もどし pos 204, 454 : mes "MNega(170,204,85)" ; 適当な値でネガポジモドキる color %10101010, %11001100, %01010101 pos 204, 472 : gcopy 0, 204, 22, 192, 128 : ImgP_FilterNega 192, 128 color 0, 0, 0 : randomize ; 色もどし pos 404, 454 : mes "NRotateFlip 270°MIRROR" ; 立ててひっくり返す pos 404, 472 : ImgP_RotateFlip 7, 0, 204, 22, 192, 128 pos 604, 454 : mes "OFitSize+ImgP_gzoom" ; 只の2倍にならないように計算 ImgP_CalcFitSize ResW, ResH, 64, 64, 200, 110 pos 600 + (200 - ResW) / 2, 600 - 128 + (110 - ResH) / 2 ; センタリング if rnd(100) < 90 { ImgP_gzoom ResW, ResH, 1, 192, 192, 64, 64 ; アップでもキレイかな? } else { ImgP_gzoom ResW, ResH, 1, 320, 256, 64, 64 ; たまにエンカウントします。 } pos 720, 600 - 18 : mes "(C)衣日和" ; ↑これの分をあけた。 ; redraw 1 ; ←APIトラップ。うちのモジュールは大丈夫だと信じたい。。。 ; http://www.tvg.ne.jp/menyukko/ ; Copyright(C) 2014-2015 衣日和 All rights reserved.
#include "a2d.hsp" ; アルファチャンネル・透過情報を持つ画像を選択。 dialog "png;*.gif", 16 : if stat == 0 : end alCreateImageByFile 0, refstr X = alGetWidth() Y = alGetHeight() screen 1, X * 2, Y ; 画像からαチャンネルを除いたプレーン画像を取り出す。 cmatrix(MAT_R) = 1.0, 0.0, 0.0, 0.0, 0.0 cmatrix(MAT_G) = 0.0, 1.0, 0.0, 0.0, 0.0 cmatrix(MAT_B) = 0.0, 0.0, 1.0, 0.0, 0.0 cmatrix(MAT_A) = 0.0, 0.0, 0.0, 0.0, 1.0 alCopyModeColorMatrix cmatrix alCopyImageToScreen 0, 1, 0, 0 ; 画像を左に。 ; 画像からαチャンネルを取り出したマスクを作る。 cmatrix(MAT_R) = 0.0, 0.0, 0.0, 1.0, 0.0 cmatrix(MAT_G) = 0.0, 0.0, 0.0, 1.0, 0.0 cmatrix(MAT_B) = 0.0, 0.0, 0.0, 1.0, 0.0 cmatrix(MAT_A) = 0.0, 0.0, 0.0, 0.0, 1.0 alCopyModeColorMatrix cmatrix alCopyImageToScreen 0, 1, X, 0 ; マスクを右に。 redraw 1 ; 上で設定したマトリックスをリセットする。 alResetCopyMode ; と言うかもう使わないけどね。 ; 描画してみよう。 gsel 0 : picload dir_tv + "bg04.jpg" gmode 7, X, Y : gcopy 1 ; http://www.tvg.ne.jp/menyukko/ ; Copyright(C) 2012-2014 衣日和 All rights reserved.そう、コレコレ。改めてArtlet2Dは偉大だなと…痛感したですよ。