今だけ人気マンガ100円レンタル特集♪

レポートで1024×1024ピクセルの画像を、間引いて256×256の画像にしろというのが出されました。画像はrawファイルです。
それで、とりあえず画像を読み込んで、出力するプログラムを書いてみたんですが、コンパイルは出来るのに実行すると不正な処理とけいこくがでてきてしまいます。
ソースは

#include<stdio.h>
main()
{
unsigned char in[1024][1024],out[1024][1024];
FILE *fp;
int i,j;
fp=fopen("aaa.raw","rb");
fread(in,sizeof(unsigned char),1024*1024,fp);
fclose(fp);
for(i=0;i<1024;i++){
for(j=0;j<1024;j++)
out[i][j]=in[i][j];
}
fp=fopen("bbb.raw","wb");
fwrite(out,sizeof(unsigned char),1024*1024,fp);
fclose(fp);
}
です。
どこがいけないのかアドバイスいただきたいです。よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

こんにちわ。


#2 のmuyoshid です。

取りあえず、もう少し小さい単位でread/write する方法のプログラムを
記載してますので、参考にしてみて下さい。
※ BUF_SZ の値を変更すると、read/write サイズを変更できます。

#include <stdio.h>
#define IN_FILE   "aaa.raw"
#define OUT_FILE  "bbb.raw"
#define BUF_SZ   8192    // Buffer Size
static int fcopy(FILE *, FILE *);

main()
{
  FILE  *rfp, *wfp;
  int   rinf;

  rfp = fopen(IN_FILE, "rb");
  if (((FILE *)NULL) == rfp) {
    printf("File \"%s\" cannot open.\n", IN_FILE);
    exit(-1);
  }
  wfp = fopen(OUT_FILE, "wb");
  if (((FILE *)NULL) == wfp) {
    printf("File \"%s\" cannot open.\n", OUT_FILE);
    exit(-1);
  }
  rinf = fcopy(rfp, wfp);
  fclose(rfp);
  fclose(wfp);
  printf("fcopy() = %d\n", rinf);
  exit(rinf);
}

static int
fcopy(FILE *rfp, FILE *wfp)
{
  unsigned char  in_buf[BUF_SZ], out_buf[BUF_SZ];
  int       rinf;

  while(!feof(rfp)) {
    rinf = fread((void *)in_buf, 1, BUF_SZ, rfp);
    if (rinf < 0) {
      printf("File read error.\n");
      return(-1);
    }
    memcpy((void *)out_buf, (void *)in_buf, BUF_SZ);
    rinf = fwrite((void *)out_buf, 1, rinf, wfp);
    if (rinf < 0) {
      printf("File write error.\n");
      return(-1);
    }
  }
  return(0);
}
    • good
    • 1
この回答へのお礼

わざわざありがとうございます。とても参考になりました。
何箇所か分からない関数もあったけど、なんとかなりました。
ありがとうございます。

お礼日時:2002/11/07 21:53

こんにちわ。



mickjey2 さんもおっしゃられていますが、Stack Orverflow の可能性
が高いですね。
→ ローカル変数が獲得される領域を超えて、変数を宣言したと言う事です。
解決策としては、
 1) malloc で領域を獲得する。
 2) in, out 変数をmain 関数の外で宣言する。
 3) 一気にデータを読まずに、もう少し小さい単位でデータをread/write する。
といったところでしょうか?
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
何とか動きました。

お礼日時:2002/11/06 15:26

>unsigned char in[1024][1024],out[1024][1024];


動的に malloc などで確保するようにしてみてください。

これでは一つの配列のサイズが、1Mbyteになります。
実行時にこのサイズが確保できていない可能性が高いです。

一般に静的に確保できる変数のサイズはそれほど大きくありません。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
お礼遅くなってすいません。mallocの使い方がわからなくて調べたりしてたら遅くなっちゃいました。
なんとか動きました。ありがとうございます。

お礼日時:2002/11/06 15:34

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QRAW画像高速表示について

画像処理ソフトの研究を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));
 }
}

画像処理ソフトの研究をc言語で行っています。
GUIの導入を目指してVC++の勉強を始めたのですが、RAW画像をうまく表示できず困っています。
現在練習と言うことで、スクロールバーの値によって画像を二値化して表示する処理を行っています。
表示部分を以下のように書いた(ほとんど本を丸写したので意味もちゃんとわかっていませんが)のですが、動作が遅すぎて困っています。
(IMG:unsigned char型の二次元配列にRAWデータを格納したもの)
高速で表示することはできないのでしょうか?
アドバイス等、よ...続きを読む

Aベストアンサー

 こんばんは。補足いただきました。

>>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);

 こんばんは。補足いただきました。

>>CONST VOID *lpvBitsにm_arrdwImage
>>CONST BITMAPINFO *lpbmiにビットマップヘッダ...
>>と言うことでしょうか?
 はい。

>>ビットマップのヘッダについても勉強した方が良いのでしょうか?
 24ビットと32ビットの二つの使用方法位には慣れた方が良いかも知れません。
 24ビットの方がヘッダの準備が簡単なのですが、イメージが3バイトで1ピクセルである為、ループで変換等をする様な場面では面倒です。
 そう言った意味では32ビットの方が簡単ですが、ヘ...続きを読む

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

QOpenCVで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;
}
========================================================

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
画像サイズはわかっているの...続きを読む

Aベストアンサー

そのURLのRAWデータというのは、 R1バイト,G1バイト,B1バイトが画素数だけ単純に並んだバイナリーデータです
「テキスト形式のヘッダーありのRAW画像(カラー)」ではありません。

具体的なフォーマットが書いてないので、具体的にどうすればいいかなんてわかりません。
・ヘッダを読み込み→strtolやscanf系で数値へ
・ヘッダに合せてcvCreatMat
・画素のデータをscanf系かstrtol等で数値へ→cvMatに

という感じになるのでは

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Qraw形式からbmp形式への書き込み (画像処理)

今、raw形式のファイルを読み込んで、bmp形式への書き込みを
行うプログラムを作成しているのですがうまくいきません.

作成したプログラムの一部は以下のようになっています.

------------------rawファイルを読み込む関数の一部-------------
//1次元配列の確保
tmp=us_Calloc2(width,height);
//画像の読み込み
fread(tmp,sizeof(unsigned short),width*height,fp);
//2次元配列の確保
img->data=us_Calloc1(width,height);
//1次元配列から2次元配列にデータを移動する
for(i=0; i<height; i++){
for(j=0; j<width; j++){
img->data[i][j]=tmp[(width*i)+j];
}
}
------------------------------------------------------------
--------------bmpファイルに書きこむ(一部)--------------
//bufのメモリ領域の確保
buf=us_Calloc2(width,height);

for(i=0; i<height; i++){
for(j=0; j<width; j++){
buf[(width*i)+j]=img->data[i][j];
}
}
//BMPのファイルヘッダーの出力(省略)
//BMPの情報ヘッダーの出力(省略)
//画像データの出力
if(fwrite(buf,sizeof(unsigned short),size,fp)!=size){
printf("画像をBMPに書き込むことができませんでした.\n");
free(buf);
fclose(fp);
exit(-1);
}
}

このように書いたのですが、うまくBMPファイルに出力できません.

アドバイスよろしくお願いします.

今、raw形式のファイルを読み込んで、bmp形式への書き込みを
行うプログラムを作成しているのですがうまくいきません.

作成したプログラムの一部は以下のようになっています.

------------------rawファイルを読み込む関数の一部-------------
//1次元配列の確保
tmp=us_Calloc2(width,height);
//画像の読み込み
fread(tmp,sizeof(unsigned short),width*height,fp);
//2次元配列の確保
img->data=us_Calloc1(width,height);
//1次元配列から2次元配列にデータを移動する
for(i=0; i<height; ...続きを読む

Aベストアンサー

うーむ。流石にこれだけではちょっと判らないですね。
取り敢えず

//画像データの出力
if(fwrite(buf,sizeof(unsigned short),size,fp)!=size)

↑は画像1ピクセルにつき16ビットと言う事でしょうか?
BMP情報ヘッダーの設定が16ビット用のビットフィールドに設定されていますか?

私はRAWの事は知らないのですが、RAWからBMPに変換する際、16ビット用のビットフィールドに対応したRGB5:6:5の配置をしないと正しく表示されないのでは?

BMPへの変換は24ビットもしくは32ビットにすると楽です。

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Qビットマップ画像を読み込むプログラムがうまく行きません。困ってます…。

こんにちは。大学4年のyu-tinと申します。
現在、大学の研究で使用するためのプログラムとして、以下の機能を持ったプログラム作りに取り込んでいます。

1)ビットマップ画像(グレースケール、縦480×横640pixel)を読み込み、
 その画像の1つ1つの画素の輝度値を表示させる
2)読み込んだビットマップ画像を出力させる

しかし、作成したプログラムがうまく行きません。以下の3つの問題が発生しています。

a)0行0列~1行383列までの画素値がおかしい。
 (0,0,0,0,1,1,1,0,2,2,2,0,3,3,3,0,…,254,0,255,255,255,0 となっている)
b)出力した画像の最上部2行程度に、細くて黒い線が表示される。
 (読み込んだ画像と全く同じ画像を出力させたい)
c)出力した画像が、”ディスクエラー”によりPhotoshopで開けない。
 (ペイントでは開ける)

その問題のプログラムは、以下の通りです。
しかし、このプログラムは、他人のプログラムに改良を加えて作成したものです。なので、このプログラム自体、私自身が完璧に理解できていない状況です。

私は、プログラミングに関しては初心者に近いので、丁寧に教えて頂けると大変助かります。
研究が先に進まず、大変困っています…。みなさま、本当に、本当によろしくお願い致します。



//ビットマップ画像に関するプログラム。
//画像の表示と輝度値の表示を行う。

#include<stdio.h>
#include<windows.h>
#include<stdlib.h>

#define X_SIZE 640  //画像の横幅(ピクセル数)
#define Y_SIZE 480  //画像の縦幅(ピクセル数)
#define Z_SIZE 1    //1つの画素に含まれる色の数

void *malloc(size_t size);

void main(void)
{
 int i, j, k;   //ループ用変数 i…縦の画素用, j…横の画素用, k…色数用
 int x=0;    //画像の横幅(ピクセル数)*/
 int y=0;     //画像の縦幅(ピクセル数)
 FILE *fp;

/***********元画像データのメモリ確保*********/
 BYTE ***mae;
 mae=(BYTE ***)malloc(sizeof(BYTE **)*Y_SIZE);
 for(i = 0; i < Y_SIZE; i++){
  mae[i]=(BYTE **)malloc(sizeof(BYTE *)*X_SIZE);
 }
 for(i = 0; i < Y_SIZE; i++){
  for(j = 0; j < X_SIZE; j++){
   mae[i][j]=(BYTE *)malloc(sizeof(BYTE)*Z_SIZE);
  }
 }

/*******画像の読み込み・輝度値の表示*******/
 fp=fopen("sample1.bmp","rb");   //画像”sample1”を開く

 BITMAPFILEHEADER bmfh;
 BITMAPINFOHEADER bmih;

 fread(&bmfh,sizeof(bmfh),1,fp);
 fread(&bmih,sizeof(bmih),1,fp);

 x=bmih.biWidth;  //インフォヘッダに含まれる画像の幅情報をxに代入
 y=bmih.biHeight;  //インフォヘッダに含まれる画像の高さ情報をyに代入

 for(i = 0; i < y ;i++){
  for(j = 0; j < x; j++){
   fread(&mae[i][j][0],sizeof(BYTE),1,fp);
   if(i<640 && j<480)printf("%d, %d, %d\n",i, j, mae[i][j][0]);   //輝度値を表示
  }
 }
 fclose(fp);

/**************画像の表示*************/
 //画像”sample1”を”sample2”という名前で出力する
 fp = fopen("sample2.bmp" ,"wb");

 //ヘッダの書き込み
 fwrite(&bmfh,sizeof(bmfh),1,fp);
 fwrite(&bmih,sizeof(bmih),1,fp);

 for(i = 0; i < bmih.biHeight; i++){
  for(j = 0; j < bmih.biWidth; j++){
   fwrite(&mae[i][j][0],sizeof(BYTE),1,fp);
  }
 }
 fclose(fp);  //ファイルをクローズ

}

こんにちは。大学4年のyu-tinと申します。
現在、大学の研究で使用するためのプログラムとして、以下の機能を持ったプログラム作りに取り込んでいます。

1)ビットマップ画像(グレースケール、縦480×横640pixel)を読み込み、
 その画像の1つ1つの画素の輝度値を表示させる
2)読み込んだビットマップ画像を出力させる

しかし、作成したプログラムがうまく行きません。以下の3つの問題が発生しています。

a)0行0列~1行383列までの画素値がおかしい。
 (0,0,0,0,1,1,1,0,2,2,2,0,3...続きを読む

Aベストアンサー

ビットマップファイルにはビット深度が24ビット未満の場合
このファイルで使用されるパレットが登録されています
BITMAPINFOHEADER と 実際のビットイメージの間に
RGBA*何色といったパレットが存在します
グレースケールの8bitなら256個です
何個あるかは BITMAPINFOHEADERのbiClrUsedがそれに当ります
これが0ならbiBitCountをビットシフトして求めます
1 << biBitCountが個数になります
実際のバイトデータとしては
(1 << biBitCount) * sizeof(RGBQ) バイト存在します

したがって
BYTE* pPalette = (BYTE*)calloc( sizeof(RGBQ), (1 << biBitCount) );
とバッファを宣言して

fread(&bmih,sizeof(bmih),1,fp);
の後で
fread( pPalette, sizeof(RGBQ), (1 << biBitCount), fp );
を実行してから
色情報を取得しましょう

書き出すときも同じように
fwrite(&bmih,sizeof(bmih),1,fp);
の後で
fwrite( pPalette, sizeof(RGBQ), (1 << biBitCount), fp );
を実行します

あと動的に確保したバッファは使い終わったら free()で開放しましょう

return 0;の前に
 free( pPalette );
 for(i = 0; i < Y_SIZE; i++){
  for(j = 0; j < X_SIZE; j++){
   free(mae[i][j]);
  }
 }
 for(i = 0; i < Y_SIZE; i++){
  free(mae[i]);
 }
 free(mae);
といった具合に 逆順に開放していきます

ビットマップファイルにはビット深度が24ビット未満の場合
このファイルで使用されるパレットが登録されています
BITMAPINFOHEADER と 実際のビットイメージの間に
RGBA*何色といったパレットが存在します
グレースケールの8bitなら256個です
何個あるかは BITMAPINFOHEADERのbiClrUsedがそれに当ります
これが0ならbiBitCountをビットシフトして求めます
1 << biBitCountが個数になります
実際のバイトデータとしては
(1 << biBitCount) * sizeof(RGBQ) バイト存在します

したがって
BYTE* pPalette...続きを読む

Q画像を表示するには

C言語をおぼえたてなんですが
文字はprintfで表示するやり方がわかるんですが
画像はどのように表示するのでしょうか?

Aベストアンサー

★アドバイス
・コンソール・アプリケーションでは画像を出せません。
 C言語でも命令(関数)が存在しません。
 画像を表示するには GUI アプリケーションで作る必要があります。
>C言語をおぼえたてなんですが
 ↑
 画像を出す(描画)するにはまだまだ時間が掛かりそうですね。
 でもミニゲームとしてなら次のリンクをどうぞ。
 (1)http://www.nhk.or.tv/kow/program/index.php→『テトリスの作り方』
 コンソール・アプリケーションでも文字を利用してテトリスが作れるようです。
・あと画像を使った場合は GUI アプリケーションになりますが、こちらは次のサイトを
 参考にして下さい。サンプル・ソースをダウンロードできます。
 (2)http://codezine.jp/a/article/aid/207.aspx→『落ち物ゲームの作り方 第1回:「TETRA」編』
 (3)http://codezine.jp/a/article/aid/228.aspx→『落ち物ゲームの作り方 第2回:「聖夜の落とし物」編』
 ダウンロードしてソースファイルを見て下さい。
 C言語ですが知らないような関数名がたくさん使われています。
 これは Win32 API の関数群です。C言語の標準関数とは別の種類です。
 Windows OS では内部はすべて Win32 API を使って処理されています。
 公開されている関数以外にも非公開関数もあります。まぁ、当然かな。
・今後のために GUI アプリケーションのサイトと本を紹介します。
 お決まりですが下のサイトを参考にして下さい。
 http://www.kumei.ne.jp/c_lang/→『猫でもわかるプログラミング』SDK編を読むこと。
 http://wisdom.sakura.ne.jp/system/winapi/→『Win32 API入門』本もお勧め。
 http://www.geocities.jp/ky_webid/win32c/index.html→『Win32API(C言語)編』お勉強サイトです。
・以上。

参考URL:http://www.amazon.co.jp/dp/4797333332/

★アドバイス
・コンソール・アプリケーションでは画像を出せません。
 C言語でも命令(関数)が存在しません。
 画像を表示するには GUI アプリケーションで作る必要があります。
>C言語をおぼえたてなんですが
 ↑
 画像を出す(描画)するにはまだまだ時間が掛かりそうですね。
 でもミニゲームとしてなら次のリンクをどうぞ。
 (1)http://www.nhk.or.tv/kow/program/index.php→『テトリスの作り方』
 コンソール・アプリケーションでも文字を利用してテトリスが作れるようです。
・あと画像を使...続きを読む

Qバイナリファイルの読み込み(C言語)

raw(音楽ファイル)データを配列rawに読み込みたいのですが,バイナリファイルの読み込み方がわかりません.

サンプルで以下のようなソース(途中略)があるのですが,
・なぜrawの型としてshortを使っているのか
・データ数の半分(file_size = ftell(fp) / 2)しか読み込んでいない
・fgetc(fp) << 8
あたりの意味がわからないので教えて下さい.

--------------------------------------------------------
short *raw;

if((fp=fopen(argv[1], "rb")) == NULL){
fprintf(stderr, "can't open %s.\n", argv[1]);
exit(1);
}
fseek(fp, 0, SEEK_END);
file_size = ftell(fp) / 2;
fseek(fp, 0, SEEK_SET);

raw = (short *)malloc((size_t)(file_size * sizeof(short)));
if(raw == NULL){
fprintf(stderr, "malloc error\n");
exit(1);
}
for(i=0;i<file_size;i++)
raw[i] = (short)((fgetc(fp) << 8) | fgetc(fp));
-----------------------------------------------------

raw(音楽ファイル)データを配列rawに読み込みたいのですが,バイナリファイルの読み込み方がわかりません.

サンプルで以下のようなソース(途中略)があるのですが,
・なぜrawの型としてshortを使っているのか
・データ数の半分(file_size = ftell(fp) / 2)しか読み込んでいない
・fgetc(fp) << 8
あたりの意味がわからないので教えて下さい.

--------------------------------------------------------
short *raw;

if((fp=fopen(argv[1], "rb")) == NULL){
fprintf(stderr, "can't open %s....続きを読む

Aベストアンサー

動作自体はNo.1,No.2の方のとおりですが、このサンプルには不都合な点が2点あります。

>file_size = ftell(fp) / 2;
2というマジックナンバを使っている、正式にはsizeof(short)でないとまずい。
file_size = ftell(fp) / sizeof(short);

>raw[i] = (short)((fgetc(fp) << 8) | fgetc(fp));
fgetcを式の中で2回呼び出している、C言語規格では未定義の動作で、fgetcを実行する順序がどうなるか分からないので、下のように書かないと駄目。
raw[i] = fgetc(fp) << 8;
raw[i] |= fgetc(fp);
または
raw[i] = fgetc(fp);
raw[i] |= fgetc(fp) << 8;
どちらかになるかは、元データのエンディアンによります。

Q画像を読み込む配列の確保。

C言語について質問です。
画像を読み込む時、その画像の幅、高さを入力し、そのサイズに見合った配列を確保します。その後ファイル名を入力し、配列に読み込むプログラムを作成しました。

メインの部分のみ記述します。

int xsize, ysize, i;
unsigned char **src;
char filename[30];
FILE *fp;

printf("ファイル名を入力してください:"); scanf("%s", filename);
printf("画像の幅:");scanf("%d", &xsize);
printf("画像の高さ:");scanf("%d", &ysize);

src = (unsigned char **)malloc(sizeof(unsigned char *) * ysize);
for(i=0; i<ysize; i++)
src[i] = (unsigned char *)malloc(sizeof(unsigned char) * xsize);
fp = fopen(filename, "rb");
fread(src[0], sizeof(unsigned char), xsize * ysize, fp);


このように記述し、エラーもなく実行できたのですが、srcをこのまま出力すると変?な画像となって出力されてしまいました。
上のように記述した場合、矛盾する場所はあるでしょうか?
そして、この方法以外に配列を確保する方法はあるでしょうか?

C言語について質問です。
画像を読み込む時、その画像の幅、高さを入力し、そのサイズに見合った配列を確保します。その後ファイル名を入力し、配列に読み込むプログラムを作成しました。

メインの部分のみ記述します。

int xsize, ysize, i;
unsigned char **src;
char filename[30];
FILE *fp;

printf("ファイル名を入力してください:"); scanf("%s", filename);
printf("画像の幅:");scanf("%d", &xsize);
printf("画像の高さ:");scanf("%d", &ysize);

src = (unsigned char **)malloc(si...続きを読む

Aベストアンサー

★最初に ysize 分のポインタを管理領域と呼んでいません。
・プログラマが malloc(1000) として 1000 バイトを確保した場合、
 実際のメモリ上には
 (1)malloc() 関数がメモリ確保の管理情報を数バイト保持(8~16バイトほど)
 (2)実際にプログラマが使用できる 1000 バイトの領域
 となります。つまり、使用できる 1000 バイトの領域の先頭に数バイトのメモリ管理情報が
 存在するのです。
・詳しい内部の仕組みは分かりませんが、確保したメモリ領域をリストデータで管理していると
 思います。リストデータはポインタで次々にデータをチェインしますよね。
 そのとき、次のデータ位置を表すポインタや確保サイズなどの数バイトが malloc() 関数などの
 メモリ管理情報(領域)として存在するわけです。
・以上を踏まえて回答 No.4 を読んでみて下さい。
 もう少し分かりやすく説明すると
 char *a = malloc(1000);
 char *b = malloc(2000);
 char *c = malloc(3000);
 char *d = malloc(4000);
 の4つのメモリは合計で 10000 バイト確保され 10000 バイトを使用できます。
 でも、実際のメモリ上には、メモリ管理情報(領域)=ヘッダが存在しますので
 a…8 + 1000
 b…8 + 2000
 c…8 + 3000
 d…8 + 4000
 で合計 10032 バイトのメモリを消費します。なお、8 バイトが管理情報ですが、昔使っていた
 コンパイラを調べたときのサイズです。今はどれくらいか分かりませんが数バイトはあります。
・メモリを節約したい場合は、回答者 No.5 さんのマクロ関数が一番節約できると思います。
 前回も同じような感じでアドバイスしたときにマクロ関数を紹介しようと思いましたが、
 それを使うのがスッキリしなくて unsigned char **src を使って src[y][x] とアクセスしたいのかと
 思いましたのでマクロ使用の紹介は控えました。が、他の回答者さんのお礼にマクロ関数のことが
 よく分からないとなっていましたね。今回はマクロ関数を利用する方がメモリを節約できます。
・マクロ関数を利用すれば、画像の横×高さのサイズ分だけ確保すればよいので src[] のポインタ分の
 メモリは節約できます。
・以上。malloc() などは『実際のメモリ使用量=メモリ管理情報(領域)+確保サイズ』です。

★最初に ysize 分のポインタを管理領域と呼んでいません。
・プログラマが malloc(1000) として 1000 バイトを確保した場合、
 実際のメモリ上には
 (1)malloc() 関数がメモリ確保の管理情報を数バイト保持(8~16バイトほど)
 (2)実際にプログラマが使用できる 1000 バイトの領域
 となります。つまり、使用できる 1000 バイトの領域の先頭に数バイトのメモリ管理情報が
 存在するのです。
・詳しい内部の仕組みは分かりませんが、確保したメモリ領域をリストデータで管理していると
 思います。リ...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング