C语言读图外加图像处理求答疑

时间:2022-07-17 01:44:45
用C语言读入一张jpg格式的图片,图片像素390*260,我想用fread函数读取,现在有两个问题,frea(buffer, size, count, fp),这个size和count应该怎么设置,是否是将size=1,count=390,然后分260次将,像素读取到一个二维矩阵中;问题2:这样读进来的数据,是否是图像的灰度矩阵,还是包含了一些其他信息?比如头信息

其次,如果我把灰度像素读到矩阵里面后,我只要对矩阵做直方图均衡处理,再把处理后的像素值写入一个新文件,那么就生成新的处理后的图片了吗?

12 个解决方案

#1


首先你要了解jpg文件的存储格式,然后才能知道怎么去读

#2


JPEG 原理详细实例分析及其在嵌入式 Linux 中的应用
http://www.ibm.com/developerworks/cn/linux/l-cn-jpeg/

#3


能不能举个小例子,以代码的形式

#4


#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
char pBuffer[390*283];
int n=0, i;

fp = fopen("a.jpg","rb");
if(!fp)
{
printf("文件打开失败");
return -1;
}
while(!feof(fp)){
  fread(pBuffer, 1, 1, fp);   
  n++;
}
  for(i=0;i<n;i++)
  printf("  %d  ",pBuffer[i]);
printf("%d",n);
  return 0;
}

#5


运行了一下 能通过,但查看的数字貌似不对

#6


jpg文件格式我不知道
bmp图片如果你用c读的话,是要自己解析文件头的。
比如你的图像是390*260=101400个像素值,你会发现其实这个文件的大小是101400+xxx;
多出来的xxx大小就是文件头等信息,包含了这个文件的色素通道调色板等等。
需要自己在c中写个struct来读。

jpg据说压缩过,所以文件应该小于101400,但是同样包含文件头信息头等内容需要自己写struct去读。
代码比较麻烦其实。

#7


引用 5 楼 xr_zy1110 的回复:
运行了一下 能通过,但查看的数字貌似不对

你看看是不是pBuffer根本没读满,后面有很多元素是0,而且你这样没读文件头。

#8


引用 7 楼 u012947309 的回复:
Quote: 引用 5 楼 xr_zy1110 的回复:

运行了一下 能通过,但查看的数字貌似不对

你看看是不是pBuffer根本没读满,后面有很多元素是0,而且你这样没读文件头。

运行了一下 全部显示的是-52

#9


仅供参考:
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")

using namespace std;
using namespace Gdiplus;

int main() {
    GdiplusStartupInput gdiplusstartupinput;
    ULONG_PTR gdiplustoken;
    GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);

    wstring infilename(L"1.jpg");
    string outfilename("color.txt");

    Bitmap* bmp = new Bitmap(infilename.c_str());
    UINT height = bmp->GetHeight();
    UINT width  = bmp->GetWidth();
    cout << "width " << width << ", height " << height << endl;

    Color color;
    ofstream fout(outfilename.c_str());

    for (UINT y = 0; y < height; y++)
    for (UINT x = 0; x < width ; x++) {
            bmp->GetPixel(x, y, &color);
            fout << x << "," << y << ";"
                 << (int)color.GetRed()   << ","
                 << (int)color.GetGreen() << ","
                 << (int)color.GetBlue()  << endl;
    }

    fout.close();

    delete bmp;
    GdiplusShutdown(gdiplustoken);
    return 0;
}

#10


libjpeg-turbo是用的最多的jpeg开源解码库,可以试试看,楼主的想法是bmp格式才可以,那也要去掉文件头

#11


JPEG图片是经过熵编码的,直接用fread读文件到缓冲区,缓冲区的数据是未解码的不可理解的。
可以用某种图像库函数读取JPG文件,然后可以操作它的每一个像素。

#12


先了解一下JPEG格式再提问。

#1


首先你要了解jpg文件的存储格式,然后才能知道怎么去读

#2


JPEG 原理详细实例分析及其在嵌入式 Linux 中的应用
http://www.ibm.com/developerworks/cn/linux/l-cn-jpeg/

#3


能不能举个小例子,以代码的形式

#4


#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
char pBuffer[390*283];
int n=0, i;

fp = fopen("a.jpg","rb");
if(!fp)
{
printf("文件打开失败");
return -1;
}
while(!feof(fp)){
  fread(pBuffer, 1, 1, fp);   
  n++;
}
  for(i=0;i<n;i++)
  printf("  %d  ",pBuffer[i]);
printf("%d",n);
  return 0;
}

#5


运行了一下 能通过,但查看的数字貌似不对

#6


jpg文件格式我不知道
bmp图片如果你用c读的话,是要自己解析文件头的。
比如你的图像是390*260=101400个像素值,你会发现其实这个文件的大小是101400+xxx;
多出来的xxx大小就是文件头等信息,包含了这个文件的色素通道调色板等等。
需要自己在c中写个struct来读。

jpg据说压缩过,所以文件应该小于101400,但是同样包含文件头信息头等内容需要自己写struct去读。
代码比较麻烦其实。

#7


引用 5 楼 xr_zy1110 的回复:
运行了一下 能通过,但查看的数字貌似不对

你看看是不是pBuffer根本没读满,后面有很多元素是0,而且你这样没读文件头。

#8


引用 7 楼 u012947309 的回复:
Quote: 引用 5 楼 xr_zy1110 的回复:

运行了一下 能通过,但查看的数字貌似不对

你看看是不是pBuffer根本没读满,后面有很多元素是0,而且你这样没读文件头。

运行了一下 全部显示的是-52

#9


仅供参考:
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")

using namespace std;
using namespace Gdiplus;

int main() {
    GdiplusStartupInput gdiplusstartupinput;
    ULONG_PTR gdiplustoken;
    GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);

    wstring infilename(L"1.jpg");
    string outfilename("color.txt");

    Bitmap* bmp = new Bitmap(infilename.c_str());
    UINT height = bmp->GetHeight();
    UINT width  = bmp->GetWidth();
    cout << "width " << width << ", height " << height << endl;

    Color color;
    ofstream fout(outfilename.c_str());

    for (UINT y = 0; y < height; y++)
    for (UINT x = 0; x < width ; x++) {
            bmp->GetPixel(x, y, &color);
            fout << x << "," << y << ";"
                 << (int)color.GetRed()   << ","
                 << (int)color.GetGreen() << ","
                 << (int)color.GetBlue()  << endl;
    }

    fout.close();

    delete bmp;
    GdiplusShutdown(gdiplustoken);
    return 0;
}

#10


libjpeg-turbo是用的最多的jpeg开源解码库,可以试试看,楼主的想法是bmp格式才可以,那也要去掉文件头

#11


JPEG图片是经过熵编码的,直接用fread读文件到缓冲区,缓冲区的数据是未解码的不可理解的。
可以用某种图像库函数读取JPG文件,然后可以操作它的每一个像素。

#12


先了解一下JPEG格式再提问。