MM_ANISOTROPICモードで縮小時に補完したい – プログラミング – Home

MM_ANISOTROPICモードで縮...
 
通知
すべてクリア

[解決済] MM_ANISOTROPICモードで縮小時に補完したい


亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

VC2008 MFC です。
MM_ANISOTROPICを使って、描画の拡大縮小機能を実装しています。
以下のテスト処理では、固定で枠付きの太い線を1/10に縮小表示していますが、
重ねて描画しているため、枠が欠けてしまいます。

void CTestDlg::OnPaint()
{
CPen pen1, pen2;
pen1.CreatePen(PS_SOLID, 50, RGB(0, 0, 0));
pen2.CreatePen(PS_SOLID, 40, RGB(255, 255, 255));

CPaintDC dc(this);
dc.SaveDC();
dc.SetMapMode(MM_ANISOTROPIC);
dc.SetWindowExt(10, 10);
dc.SetViewportExt(1, 1);
dc.FillSolidRect(0, 0, 100, 200, RGB(255, 255, 255));
dc.SelectObject(&pen1);
dc.MoveTo(50, 50);
dc.LineTo(50, 150);
dc.SelectObject(&pen2);
dc.MoveTo(50, 50);
dc.LineTo(50, 150);
dc.RestoreDC(-1);
}

これを、MM_ANISOTROPICを使わずに、事前に大きいサイズのまま描いておき、
それをStretchBltで縮小コピーすると、枠も綺麗に表示されます。

void CTestDlg::OnPaint()
{
CPen pen1, pen2;
pen1.CreatePen(PS_SOLID, 50, RGB(0, 0, 0));
pen2.CreatePen(PS_SOLID, 40, RGB(255, 255, 255));

CPaintDC dc(this);
CBitmap bitmapMem;
bitmapMem.CreateCompatibleBitmap(&dc, 100, 200);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
dcMem.SaveDC();
dcMem.SelectObject(&bitmapMem);
dcMem.FillSolidRect(0, 0, 100, 200, RGB(255, 255, 255));
dcMem.SelectObject(&pen1);
dcMem.MoveTo(50, 50);
dcMem.LineTo(50, 150);
dcMem.SelectObject(&pen2);
dcMem.MoveTo(50, 50);
dcMem.LineTo(50, 150);
dc.SetStretchBltMode(HALFTONE);
dc.StretchBlt(0, 0, 10, 20, &dcMem, 0, 0, 100, 200, SRCCOPY);
dcMem.RestoreDC(-1);
}

MM_ANISOTROPICのマッピングを使ったまま、
縮小時に綺麗に補完してくれるモードは無いものなのでしょうか?


引用未解決
トピックタグ
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 4年前
投稿: 828
 

う~んと、これは難しいですね。
とりあえず SetStretchBltMode() で転送時の伸縮モードを
いくつか試してみては、どうでしょう。だめかも知れんけど。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 4年前
投稿: 828
 

まちがったorz。マップモードで縮小すると線が消えるんですね(vv;)。

マップモードがだめならSetGraphicsMode( GM_ADVANCED)して、
SetWorldTransform()してみるとか・・・でしょうか。


返信引用
gak
 gak
(@gak)
ゲスト
結合: 21年前
投稿: 132
 

> MM_ANISOTROPICのマッピングを使ったまま、縮小時に綺麗に補完してくれるモードは無
いものなのでしょうか?
一つの方法として、gdi+ のアンチエイリアスを利用した例。

xxxxxxxx(HDC hdc) {
ULONG_PTR token;
Gdiplus::GdiplusStartupInput input;
Gdiplus::GdiplusStartup(&token, &input, NULL);
{
Gdiplus::Pen pen1(Gdiplus::Color(0, 0, 0), 50);
pen1.SetDashStyle(Gdiplus::DashStyleSolid);
pen1.SetStartCap(Gdiplus::LineCapRound);
pen1.SetEndCap(Gdiplus::LineCapRound);
Gdiplus::Pen pen2(Gdiplus::Color(255, 255, 255), 40);
pen2.SetDashStyle(Gdiplus::DashStyleSolid);
pen2.SetStartCap(Gdiplus::LineCapRound);
pen2.SetEndCap(Gdiplus::LineCapRound);

Gdiplus::Graphics graphics(hdc);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
Gdiplus::Point from(50, 50), to(50, 150);
graphics.DrawLine(&pen1, from, to);
graphics.DrawLine(&pen2, from, to);
}
Gdiplus::GdiplusShutdown(token);
}


返信引用
亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

仲澤@失業者さん、gakさん、ご意見ありがとうございます。

gakさんに提案していただいたGDI+を使う方法だと、
たしかに枠部分も表示されました。

仲澤@失業者さんに提案していただいた
SetGraphicsMode()やSetWorldTransform()などを使う方法を
いろいろ試してみてもうまく描画されないのですが、
GDIのままで描画する限りは、MM_ANISOTROPICで縮小する方法では
線の枠はうまく描けないということになってしまいますでしょうか?

枠だけでなく、他の描画もジャギーになってしまうのですが。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 4年前
投稿: 828
 

>GDIのままで描画する限りは、MM_ANISOTROPICで縮小する方法では
>線の枠はうまく描けないということになってしまいますでしょうか?

ですね。
拡大はともかく、縮小したときに良いことは何もおこりません。
自前で縮小描画をしたほうがはるかに「まし」な結果にできます。
そうなると拡大だけMAP MODEを使うわけにはいかず、結局全て
自前で実装することになるのです。もちろん出力結果がこんなもん
で満足なら話は別ですけど。
gakさんの方法は良いですね。勉強になりました。


返信引用
亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

> 拡大はともかく、縮小したときに良いことは何もおこりません。
> 自前で縮小描画をしたほうがはるかに「まし」な結果にできます。

やっぱりそうなってしまうのですね。
2年前には「MM_ANISOTROPICモードでテキストサイズがずれる」
という問題でも質問させていただきましたが、
マッピングモードで文字や図形の拡大縮小を実現するのって、
あまりよい方法ではなかったのかもしれません。
ありがとうございます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました