• ベストアンサー

RAW画像高速表示について

画像処理ソフトの研究をc言語で行っています。 GUIの導入を目指してVC++の勉強を始めたのですが、RAW画像をうまく表示できず困っています。 現在練習と言うことで、スクロールバーの値によって画像を二値化して表示する処理を行っています。 表示部分を以下のように書いた(ほとんど本を丸写したので意味もちゃんとわかっていませんが)のですが、動作が遅すぎて困っています。 (IMG:unsigned char型の二次元配列にRAWデータを格納したもの) 高速で表示することはできないのでしょうか? アドバイス等、よろしくお願いします。 void Cimage_binView::writeImg(void) {  CClientDC myDC(this);  CDC *pDC = m_pict.GetDC();  int col,row;  int I;  CRgn myRgn;  RECT rect;  m_pict.GetClientRect(&rect);  myRgn.CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);  pDC->SelectObject(&myRgn); //画像出力  for(col=0;col<256;col++)   for(row=0;row<256;row++)   {    I=IMG[col][row];        if(I<m_sbar1.GetScrollPos())I=0;//スクロールバーの値より小さければ黒    else I=255;//大きければ白にする }    pDC->SetPixel(row,col,RGB(I,I,I));  } }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

 こんばんは。補足いただきました。 >>CONST VOID *lpvBitsにm_arrdwImage >>CONST BITMAPINFO *lpbmiにビットマップヘッダ... >>と言うことでしょうか?  はい。 >>ビットマップのヘッダについても勉強した方が良いのでしょうか?  24ビットと32ビットの二つの使用方法位には慣れた方が良いかも知れません。  24ビットの方がヘッダの準備が簡単なのですが、イメージが3バイトで1ピクセルである為、ループで変換等をする様な場面では面倒です。  そう言った意味では32ビットの方が簡単ですが、ヘッダの準備が面倒になります。  以下は32ビット用のヘッダを準備します、参考程度に。 +----------------------------------------------------------------------------------- //初期化 static void InitHDR32BIT(BITMAPINFOHEADER& bmi, int width, int height) { bmi.biSize = sizeof(BITMAPINFOHEADER); bmi.biWidth = width; bmi.biHeight = height; bmi.biBitCount = 32; bmi.biPlanes = 1; bmi.biCompression = BI_BITFIELDS; bmi.biSizeImage = bmi.biWidth * bmi.biHeight * (bmi.biBitCount / 8); } //32ビット型ビットフィールドの設定 static void InitBitFields32BIT(LPRGBQUAD pRGB) { //RGBQUADとDWORDは同じサイズです。ビットフィールドを指定する場合はLPDWORDにキャストする方が楽です(16ビット等では特に) LPDWORD pBF = reinterpret_cast<LPDWORD>(pRGB); pBF[0] = 0xff0000; pBF[1] = 0x00ff00; pBF[2] = 0x0000ff; } //ヘッダを動的作成する static LPBITMAPINFO CreateHDR32BIT(int width, int height) { //ヘッダのサイズ(RGBQUAD * 3は、ビットフィールド用に必要です) const int nHDRSize = sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 3); LPBITMAPINFO pbmi = static_cast<LPBITMAPINFO>(::calloc(nHDRSize, 1)); ::InitHDR32BIT(pbmi->bmiHeader, width, height); ::InitBitFields32BIT(pbmi->bmiColors); return pbmi; } -----------------------------------------------------------------------------------+ //遠くで割り当てておく(メンバに入れておく。当然、不要になった時には::free(m_lpbmi)で消します) LPBITMAPINFO m_lpbmi = ::CreateHDR32BIT(256, 256); //ココで描写する ::SetDIBitsToDevice(pDC, 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, 0, 0, 0, pbmi->bmiHeader.biWidth, m_arrdwImage, m_lpbmi, DIB_RGB_COLORS);

snake_sato
質問者

お礼

ご丁寧に指導していただき、ありがとうございました。 お陰さまでサクサク動くようになりました! 自分ひとりではとても書けなかったと思います。 本当にありがとうございました。

その他の回答 (3)

  • Yanch
  • ベストアンサー率50% (114/225)
回答No.4

RAWイメージから、DIBTIMAPを構築するプログラムの例) -------------------- /** * unsigned longの32bitイメージデータ配列から、bitmapデータを構築する * * @param[in] hdc デバイスコンテキストハンドル * @param[in] unsigned long *pImage 入力イメージデータ(32bitの配列 * @param[in] width イメージの横幅 * @param[in] height イメージの縦幅 * @return ビットマップのハンドル(失敗時にはNULL) */ HBITMAP createBitmapFromImage32(HDC hdc, unsigned long *pImage , int width, int height) { BITMAPINFOHEADER bmih; BITMAPINFOHEADER *lpbmih; BITMAPINFO bmi; DWORD fdwInit; CONST VOID *lpbInit; BITMAPINFO *lpbmi; UINT fuUsage; HBITMAP hBitmap; memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); bmih.biSize = sizeof(bmih); bmih.biWidth = width; bmih.biHeight = -height; bmih.biPlanes = 1; bmih.biBitCount = 32; bmih.biCompression = BI_RGB; bmih.biSizeImage = 0; bmih.biXPelsPerMeter = 0; bmih.biYPelsPerMeter = 0; bmih.biClrUsed = 0; bmih.biClrImportant = 0; memset(&bmi, 0, sizeof(BITMAPINFO)); bmi.bmiHeader = bmih; lpbmih = &bmih; fdwInit = CBM_INIT; lpbInit = pImage; lpbmi = &bmi; fuUsage = DIB_RGB_COLORS; hBitmap = CreateDIBitmap(hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage); return hBitmap; } void Cimage_binView::writeImg(void) { CClientDC myDC(this); CDC *pDC = m_pict.GetDC(); int col,row; int I; CRgn myRgn; RECT rect; m_pict.GetClientRect(&rect); myRgn.CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom); pDC->SelectObject(&myRgn); unsigned long image[256][256]; unsigned char scrollPos = m_sbar1.GetScrollPos(); //画像出力 for(col=0;col<256;col++) for(row=0;row<256;row++) { I=IMG[col][row]; if(I<scrollPos) I=0;//スクロールバーの値より小さければ黒 else I=255;//大きければ白にする } image[row][col] = RGB(I, I, I); } HBITMAP hBitmap = createBitmapFromImage32(pDC->m_hDC, image, 256, 256); // 後は、BitBlt等を使って、描画する。 // 例えば、 BITMAP bitmap; memset(&bitmap, 0, sizeof(BITMAP)); GetObject(hBitmap, sizeof(BITMAP), &bitmap); HDC hdcDest = pDC->m_hDC; int nXDest = 0; int nYDest = 0; int nWidth = bitmap.bmWidth; int nHeight = bitmap.bmHeight; HDC hdcSrc = CreateCompatibleDC(hdcDest); int nXSrc = 0; int nYSrc = 0; DWORD dwRop = SRCCOPY; SelectObject(hdcSrc, hBitmap); BOOL boResult = BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight , hdcSrc, nXSrc, nYSrc, dwRop); DeleteDC(hdcSrc); } -------------------- こんな感じの関数を用意しておいてあげれば、RAWイメージからBITMAPデータを作成 出来ると思います。 RAWイメージのデータ構造もunsigned long(32bit)の配列にしておいてあげる必要がありますけどね。 HBITMAPが得られれば、後は、GDC関数での描画も出来ますので、 SetPixel()関数を呼び出す回数も減らせるのではないでしょうか。 サンプルプログラムは、コンパイルやテストしていないので、バグがあると思いますが、 ご了承ください。 >>forループなしのプログラム >とは2値化処理の部分で(各ピクセルにアクセスせずに)可能なのでしょうか? forなしには出来ませんでした。すいません。

snake_sato
質問者

お礼

ご丁寧にありがとうございます。 とても勉強になりました。

回答No.2

 こんばんは。  動作が遅すぎるのは、  pDC->SetPixel(row,col,RGB(I,I,I));  の仕業です。 「画像処理 SetPixel 重い」(検索)  http://www.google.co.jp/search?hl=ja&q=%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86%E3%80%80SetPixel%E3%80%80%E9%87%8D%E3%81%84&lr=  爆裂に重たい事で有名です。  DWORD型の配列を用意して(又は動的に)  DWORD m_arrdwImage[256*256];  I = IMG[col][row];  m_arrdwImage[idx] = RGB(I,I,I);  の様に変換してから  SetDIBitsToDevice(pDC, , , , , m_arrdwImage);  でpDCに向かって描写すると速くなると思います。  「SetDIBitsToDevice()API」  http://msdn.microsoft.com/ja-jp/library/cc410591.aspx  流れは以下の様な感じです。 //外に出しておく const int nScrollPos = m_sbar1.GetScrollPos(); //変換 for(col=0;col<256;col++) { for(row=0;row<256;row++) { I=IMG[col][row];     //大きければ白にする if(I<nScrollPos)I=0; else I=255; //一次元のインデックス const int idx = (row * 256) + col; //32ビットの配列に代入する m_arrdwImage[idx] = RGB(I,I,I); } } //ココで描写する ヘッダーの初期化などはURLを参考 ::SetDIBitsToDevice(pDC, , , , , m_arrdwImage);

snake_sato
質問者

補足

ありがとうございます。 URLを見ましたが、よくわからない部分があります。 int SetDIBitsToDevice( HDC hdc, // デバイスコンテキストのハンドル int XDest, // 転送先長方形の左上隅の x 座標 int YDest, // 転送先長方形の左上隅の y 座標 DWORD dwWidth, // 転送元長方形の幅 DWORD dwHeight, // 転送元長方形の高さ int XSrc, // 転送元長方形の左下隅の x 座標 int YSrc, // 転送元長方形の左下隅の y 座標 UINT uStartScan, // 配列内の最初の走査行 UINT cScanLines, // 走査行の数 CONST VOID *lpvBits, // DIB ビットからなる配列 CONST BITMAPINFO *lpbmi, // ビットマップ情報 UINT fuColorUse // RGB 値またはパレットインデックス ); lpvBits  バイト配列として格納されている、DIB の色データへのポインタを指定します。詳細については、「解説」を参照してください。 lpbmi  DIB についての情報を保持している 1 個の 構造体へのポインタを指定します。 ということですが、 CONST VOID *lpvBitsにm_arrdwImage CONST BITMAPINFO *lpbmiにビットマップヘッダ... と言うことでしょうか? ビットマップのヘッダについても勉強した方が良いのでしょうか? よろしくお願いします。

  • Yanch
  • ベストアンサー率50% (114/225)
回答No.1

パフォーマンスチューニングの話ですね。 こちらのプログラムの場合、 GetScrollPos()と、SetPixel()の呼び出し回数が多すぎるために、遅くなって ると予測出来ると思います。 ・呼び出し回数   GetScroll():65536回   SetPixel():65536回 なので、これを減らしてあげれば、速度が速くなると思われます。 CreateDIBitmap()とか、BitBlt()が有効かもしれないので、試してみてください。 あと、for ループなしのプログラムに書き換え可能と思われますので、 そちらも試してみてください。

snake_sato
質問者

補足

ありがとうございます。 GetScroll();をループの前に配置したら大分早くなりました。 >forループなしのプログラム とは2値化処理の部分で(各ピクセルにアクセスせずに)可能なのでしょうか?

関連するQ&A

  • OpenCVでRAW画像(カラー)を開くには

    OpenCVを使って、テキスト形式のヘッダーありのRAW画像(カラー)を、Cで書いたプログラムで開きたいのですが、 うまくいかず困っています。 “LoadRawImage”というWindowが起動しますが、真黒で何も表示されません。 RAW画像を開く関数myRawImageは以下のurlの「RAWデータの読み込みと表示」を参照させていただきました。(すみません、どうもありがとうございます。) http://wiki.livedoor.jp/mikk_ni3_92/d/raw%a5%c7%a1%bc%a5%bf%a4%ce%c6%c9%a4%df%b9%fe%a4%df%a4%c8%c9%bd%bc%a8 画像サイズはわかっているので、bmpなどに変換せず、RAWのまま開きたいのですが、どこを直せばいいのでしょうか。 どなたかヒントでも教えていただけると大変助かります、どうぞよろしくお願い致します。 //test.cpp #include <cv.h> #include <highgui.h> #include <iostream> #include <fstream> #include "raw_data_show.h" int main (int argc, char ** argv)================= { int x, y,i; uchar p1[3], p2[3]; IplImage *img1, *img2, *cp_img; img1 = myRawImage("D:\\My Pictures\\...\rawimage",500,500,3); cvShowImage("Load RawImage",img1); cvWaitKey(0); ============================================== #include <cv.h> #include <cxcore.h> #include <highgui.h> #include <iostream> #include <fstream> IplImage *myRawImage(char *filename, int w,int h,int channels) { if((channels != 3) && (channels != 1)) { std::cerr << " channel is not 3 or 1\n"; return NULL; } std::fstream ifs(filename,std::ios::in|std::ios::binary); if(!ifs.is_open()) { return NULL; } CvMat *Mat = cvCreateMat(h,w,CV_8UC3); ifs.read(reinterpret_cast<char*>(Mat->data.ptr),w*h*3); ifs.close(); IplImage img_hdr; IplImage *dst_img = cvGetImage (Mat, &img_hdr); IplImage *clone = cvCloneImage(dst_img);//クローン作成 cvReleaseImage(&dst_img); cvReleaseMat(&Mat); if(channels == 3){ for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { CvMat m; float ret = 0.0; float a[] = { float (j) / size, float (i) / size }; cvInitMatHeader (&m, 1, 2, CV_32FC1, a); ret = svm.predict (&m); switch ((int) ret) { case 1: rcolor = CV_RGB (100, 0, 0); break; case 2: rcolor = CV_RGB (0, 100, 0); break; case 3: rcolor = CV_RGB (0, 0, 100); break; } cvSet2D (img, i, j, rcolor); } } cvCvtColor(clone,clone,CV_RGBA2BGR); return clone; } ========================================================

  • MFCでボタンを押して図形を操作するには

    Visual studio 2008のMFCで、とあるプログラムを作っております。 ボタンをクリックすると円が出てきて、さらにクリックするとその下に円が表示されるというプログラムまで作りました。 void C***Dlg::OnBnClickedButton1(){ CDC* pDC=m_pict.GetDC(); CRect rect; m_pict.GetClientRect(&rect); pDC->Rectangle(&rect); CPen pen_red(PS_SOLID,1,RGB(255,0,0)); CBrush br_yellow(RGB(255,255,0)); CPen* oldpen=pDC->SelectObject(&pen_red); CBrush* oldbr=pDC->SelectObject(&br_yellow); pDC->Ellipse(-252,i-43,-212,i-3); i=i+48; UpdateWindow(); pDC->SelectObject(oldpen); pDC->SelectObject(oldbr); // TODO: ここにコントロール通知ハンドラ コードを追加します。 } とりあえずOnBnClickedButton1関数はこんな感じです。 ここから、 (1)クリックすると円が自動で動き、途中で止まり、しばし経ってから動き出してやがて上へ消えてゆく。 (2)2つ目の円も同じように動くが、1つ目の円が止まっていて重なりそうになったらその手前で止まる。 (3)1つ目の円が上に消えたら、2つ目の円が動き出し、以降は(1)と同じ動きをする。 このようなプログラムを作りたいのですが、初心者のためどのようなツールをどのように使えば良いのかわかりません。 どなたがヒントだけでもご教授頂けませんでしょうか?

  • VC++2010 で線形の描画についてですが・・

    VC++2010 で線形の描画についてまた質問なんですが、以下のように記述すると線ができなく、 点だけが動くプログラムになりました。解決方法がわからないのでよろしくお願いします。 今回のプロジェクトの目的はある機器からデータを取ってきて(1msごとに)それを1msごとに 直線として出力するプロジェクトです 電圧                    ↑          ________ ↑         |          |________→→ ーーーーーーーー  →→時間 ↑↑↑ このような線を出力しなければならないです。 以下がソースになっています。 使用環境VC++2010 MFC test10000Dlg.cpp ちなみにm_lineXとm_lineYはメンバー変数です(double型) ボタンがクリックされたときのイベント SetTimer(0, 1, NULL); void Ctest10000Dlg::OnTimer(UINT_PTR nIDEvent) { UpdateData(); after_datay = sam_data; m_xvEditX = m_lineX; m_xvEditSamd = m_lineY; m_xvEditSami = sam_i++; if(sam_i%200==0) { m_lineY -= 5; sam_i = 0; } m_lineX++; UpdateWindow(); Invalidate(FALSE); } void Ctest10000Dlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 描画のデバイス コンテキスト SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // クライアントの四角形領域内の中央 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // アイコンの描画 dc.DrawIcon(x, y, m_hIcon); } else { //****************************************************************************************************** CRect rect_dlg; GetClientRect(&rect_dlg); CBrush br_black(RGB(0,0,0)); //各色ペン CPen pen_black(PS_SOLID,1,RGB(0,0,0)); CPen pen_gray(PS_DOT,1,RGB(128,128,128)); CPen pen_blue(PS_SOLID,1,RGB(0,0,255)); CPen pen_white(PS_SOLID,1,RGB(255,255,255)); int max_y=1; if(int(m_sin+m_cos+1.0)>max_y) max_y=int(m_sin+m_cos)+1; CDC* pDC=m_pict.GetDC(); //PictureControlの大きさ取得 CRect rect; m_pict.GetClientRect(&rect); //元のブラシをoldbrに保持 CBrush* oldbr=pDC->SelectObject(&br_black); //元のペンをoldpenに保持 CPen* oldpen=pDC->SelectObject(&pen_black); //(1)背景描画(ブラシ白、ペン黒) pDC->Rectangle(&rect); //(2)中心線(黒、実線) pDC->SelectObject(&pen_blue); pDC->MoveTo(10,rect.Height()-10); pDC->LineTo(10,10); pDC->MoveTo(10,rect.Height()-10); pDC->LineTo(rect.Width()-10,rect.Height()-10); pDC->SelectObject(&pen_white); pDC->MoveTo(m_lineX,m_lineY_after); pDC->LineTo(m_lineX+1,m_lineY); pDC->SelectObject(oldbr); pDC->SelectObject(oldpen); m_lineY_after = m_lineY; UpdateData(FALSE); CDialog::OnPaint(); } } ではよろしくお願いします

  • 自作の行列クラスを継承するさいにエラーがでます

    現在、c++の学習で、自作の基底行列クラスMatrixを作成し、このクラスを継承して新たにlduMatrixを作成する事を考えています。 が、継承し、 lduMatrix a( 3, 3); a = 3; とすると、 main.C:13: warning: passing ‘double’ for argument 1 to ‘lduMatrix::lduMatrix(int)’ というエラーがでてコンパイルできずにいます。その一方で、 lduMatrix a(3,3, 3.14); とするとコンパイルはとおり、lduMatrix行列の各要素(a[1][1]など)の値をプリントさせると、[[3.14]]の値が入っていることを確認しております。 どこが間違っているのか御指導いただけると幸いです。 以下、クラスの中身です。よろしくおねがいします。 《Class: Matrix》 #include <iostream> class Matrix{ private: //! Size of row and column in Matrix int row_, col_; //! Row pointers double** m_; //! Allocate function for row-pointers void allocate(); public: Matrix(); //! Constructor with given matrix size Matrix( const int, const int ); //! Constructor with given matrix size and value fro all elements Matrix( const int, const int, const double ); //! Destructor ~Matrix(); ・・・省略・・・ double* operator[]( const int ); double* operator[]( const int ) const ; void operator=( const double ); }; /* Private functions *********************************************** */ void Matrix::allocate() { m_ = new double* [row_]; m_[0] = new double [row_*col_]; for ( int i=1; i<row_; i++ ){ m_[i] = m_[i-1] + col_; } } /* Destructor ****************************************************** */ Matrix::~Matrix(){ delete[] m_[0]; delete[] m_; } /* Constructors **************************************************** */ // NULL constructor Matrix::Matrix() : row_(0), col_(0), m_(NULL) {} // Constructor with given matrix size Matrix::Matrix( const int row, const int col ) : row_(row), col_(col) { allocate(); } // Constructor with given matrix size and value for all elements Matrix::Matrix( const int row, const int col, const double s ): row_(row), col_(col) { allocate(); double* m = m_[0]; for ( int i=0; i<row_*col_; i++ ){ m[i] = s; } } 《省略》 /* Member operators ************************************************ */ double* Matrix::operator[]( const int i ){ return m_[i]; } void Matrix::operator=( const double t ){ double* m = m_[0]; int nm = row_*col_; for ( int i=0; i<nm; i++ ) { m[i] = t; } } 《Class: lduMatrix》 class lduMatrix : public Matrix{ public: lduMatrix(); lduMatrix( const int ); lduMatrix( const int, const double ); }; lduMatrix::lduMatrix() {} lduMatrix::lduMatrix( const int mSize ) : Matrix( mSize, mSize, 0.0 ) {} lduMatrix::lduMatrix( const int mSize, const double s ) : Matrix( mSize, mSize, s ) {}

  • OpenCVで32bit ヘッダ無しRaw画像表示

    OpenCVのIPLimage構造体にヘッダ無しRaw画像を読み込んで表示させたいのですが、OpenCVではヘッダ無しRaw画像を直接読み込む関数がないため(cvLoadImageは対応せず)自作しなければいけません。まだCプログラムを勉強し始めたばかりなのでなかなか上手くいかなくて困っております。どなたか教えていただけませんか?ここまで作っみました。コンパイルはできますが、原画像どおり表示してくれません。扱う画像はレントゲン画像で512*512 32bit実数データです。 #include <cv.h> #include <highgui.h> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> int main(int argc, char *argv[]) { char infile[512]; /* (1) */ float *inputimg; /* (3) */ int i, j; int mszx, mszy; FILE *fp; IplImage* img; strcpy(infile,argv[1]); mszx = atoi(argv[2]); mszy = atoi(argv[3]); static const char* title="display"; inputimg = (float*)malloc(mszx*mszy*sizeof(float)); if((fp=fopen(infile,"rb")) == NULL) { printf("OPEN FAILED %s\n",infile); exit(0); } fread(inputimg, sizeof(float), mszx*mszy, fp); fclose(fp); img = cvCreateImage(cvSize(512,512),IPL_DEPTH_32F,1); cvSetZero(img); for (j = 0; j < mszy; j++) { for (i = 0; i < mszx; i++){ img->imageData[mszx * j + i] = inputimg[mszx * j + i]; } } cvNamedWindow(title,CV_WINDOW_AUTOSIZE); cvShowImage(title,img); cvWaitKey(0); cvDestroyWindow(title); cvReleaseImage(&img); return 0; } ここまでしかできませんでした。

  • 画像がうまく表示されません

    下のプログラムを実行すると、 最初の読みこみはうまくいくのですが、(一部出なくなる画像がありますが…) Internet Explorerの更新ボタンを押した時、 (1)の部分で止まってしまうようで、画像が表示されなくなります。 (ローカルドライブで実行した場合はうまく表示できるのですが、ネットワークで実行した場合にこのようになってしまいます) import java.applet.Applet; import java.awt.*; public class met extends Applet{ Image img[] = new Image[6]; MediaTracker mt; public void init(){ mt = new MediaTracker(this); for(int i = 0;i < 6;i++){ img[i] = getImage(getCodeBase(),i+".gif"); mt.addImage(img[i],0); } try{ mt.waitForID(0); }catch(InterruptedException e){} } public void paint(Graphics g){ // (1) if(!mt.checkID(0)){ g.clearRect(0,0,500,500); g.drawString("読み込み中",200,240); return; } g.setColor(Color.white); g.fillRect(0,0,500,500); for(int i = 0;i < 6;i++){ g.drawImage(img[i],i*50,0,this); } } }

    • ベストアンサー
    • Java
  • 行列の積を計算するプログラムがうまくいきません

    どこが間違っているのかわかる方お願いします ・行列A,Bはファイルから読み込む ・行列A,Bの積Cの計算には関数を用いる #include<stdio.h> #define ROW 10 #define COL 10 void MatrixProduct(int a[][COL],int b[][ROW],int c[][ROW],int n,int m ) { int i,j,k; for(i=0;i<n;i++){ for(j=0;j<n;j++){ c[i][j]=0; } } for(i=0;i<n;i++){ for(j=0;j<n;j++){ for(k=0;k<m;k++){ c[i][j]=c[i][j]+a[i][k]*b[k][j]; } } } } int main(void) { FILE *fp1,*fp2; char fname1[64],fname2[64]; int a[ROW][COL],b[ROW][COL],c[ROW][COL],n,m; int i,j,k; printf("Input file name ?"); scanf("%s",fname1); printf("Output file name ?"); scanf("%s",fname2); fp1=fopen(fname1,"r"); fp2=fopen(fname2,"w"); fscanf(fp1,"%d %d",&n,&m); MatrixProduct(a,b,c,n,m); for(i=0;i<n;i++){ for(j=0;j<n;j++){ fprintf(fp2,"%3d",c[i][j]); } fprintf(fp2,"\n"); } fclose(fp1); fclose(fp2); return(0); } fp1 3 4 1 2 3 4 2 3 4 5 3 4 5 6 1 2 3 2 3 4 3 4 5 4 5 6

  • Visual Studioのタイマ処理を使って描画を行うプログラムを

    Visual Studioのタイマ処理を使って描画を行うプログラムを 作成したのですがうまくいきません. プログラムの開発環境はWindows XP SP2でVC++6.0 外部に接続したセンサからのデータを50Hzで サンプリングして そのデータを元に描画を行う予定なのですが計測時間が100秒を超えると 異常終了してしまいます. 原因がよく分かりません. どうしたらよいのでしょうか? void CMyDlg::OnSamplingStart() { i=0; // サンプリング用タイマ開始 //なぜか12にするとちょうど50Hzでサンプリングする SetTimer(1,12,NULL); // 0.02秒毎タイマ割り込み,50Hz } void CMyDlg::OnTimer(UINT nIDEvent) { /* ここで,センサからのデータをサンプリングし,いろいろな計算をする. */ CDC* pDC=m_pict.GetDC(); CRect myRECT; m_pict.GetClientRect(myRECT); pDC->FillSolidRect(myRECT, RGB(255,255,255)); CPen BlueBoldPen,*OldBlueBoldPen; BlueBoldPen.CreatePen(PS_SOLID,5,RGB(0,0,255)); OldBlueBoldPen=pDC->SelectObject(&BlueBoldPen); pDC->MoveTo((int)(X0/10),(int)(Y0/10)); pDC->LineTo((int)(L3_x[i]/10),(int)(L3_y[i]/10)); pDC->LineTo((int)(C7_x[i]/10),(int)(C7_y[i]/10)); // ペンを元に戻す pDC->SelectObject(OldBlueBoldPen); BlueBoldPen.DeleteObject(); m_time=(double)i/50; UpdateData(FALSE); i=i+1; CDialog::OnTimer(nIDEvent); } 計測終了はボタンを押して終了します. どうが具体的な解決策を教えてください.

  • mfcの画像表示で、bmp表示がよくわかりません

    mfcの画像表示で、bmp表示がよくわかりません。 特に、SelectObject()でBitmapを戻す等が特によくわかりません。 今までは、そういうもんだとしてきたのですが、放っておけない事態になりまして、 相談させて下さい。 (1)下記のbmpDC.SelectObject(oldbmp)等について、その仕組みを詳細に紹介しているHPを ご存じでしたらお教えください。 (2)下記プログラムの画像の扱いで、まずい部分を、おかしいなと思われた部分をお教えください。  動作は、問題なく動作しています。BITMAPを敷き詰めるプログラムです。 CArray<HBITMAP> hBitAry; (HBITMAPを配列にしているまずさは今回は除外して下さい。) … int topX=-100-5; int topY=0; int hLen=100; int wLen=100; int yoko=0; CDC *pDC=mPict.GetDC(); for(int i=0; i<hBitAry.GetCount(); i++) { CDC bmpDC; bmpDC.CreateCompatibleDC(pDC); CBitmap *pBitmap=CBitmap::FromHandle(hBitAry.GetAt(i)); BITMAP BMP; pBitmap->GetBitmap(&BMP); CBitmap *oldbmp=bmpDC.SelectObject(pBitmap); if(yoko<3) { topX+=100+5; yoko++; } else { topX=0; topY+=100+5; yoko=0; } pDC->SetStretchBltMode(COLORONCOLOR); pDC->StretchBlt(topX,topY,100,100,&bmpDC,0,0,BMP.bmWidth,BMP.bmHeight,SRCCOPY); bmpDC.SelectObject(oldbmp); ::DeleteObject(CBitmap::FromHandle(hBitAry.GetAt(i))); } ReleaseDC(pDC); どうぞよろしくお願い致します。

  • C# Picturebox 縮小・拡大時の表示方法

    下記のようなコードで、画像の拡大・縮小を行っています。 ただ画像の縮小時、PictureBox内の余分な部分について、(1)縮小前の 画像が残像のように表示されています。 また通常、画像の拡大・縮小前の画像では画像サイズがPictureBoxよりも大きいサイズの 場合、スクロールバーを表示するようにしています。 (2)でも、画像拡大時、スクロールバーが出るには出ているのですが、画像全てを 確認できません。 (1)、(2)の問題について、解決方法をご存知の方、お願いです、、、教えてください。。。 かなり、困ってます。。。。 Bitmap img = new Bitmap(pictureBox1.Image.Tag.ToString()); //PictureBox1のGraphicsオブジェクトの作成 Graphics g = pictureBox1.CreateGraphics(); //拡大・もしくは縮小 RectangleF rect = new RectangleF(0, 0, zoom * img.Width, zoom * img.Height); g.DrawImage(img, rect); //BitmapとGraphicsオブジェクトを破棄 img.Dispose(); g.Dispose();