在C中将图像转换为黑白的问题

时间:2013-11-20 20:07:15

标签: c linux bash ubuntu

我的程序出了问题。我一直试图谷歌问题,但似乎无法找到我可以使用的东西。我对C很陌生,所以我想尽我所能。

当我尝试使用./imgconvert.c运行时,我收到以下错误:

 ./imgconvert.c: line 6: struct: command not found
 ./imgconvert.c: line 7: uint8_t: command not found
 ./imgconvert.c: line 8: syntax error near unexpected token `}'
 ./imgconvert.c: line 8: `};'

我尝试将程序编译为类似myProgram.o的内容: gcc -c imgconvert.c -o myProgram.o然后./myProgram。但是我得到了一个权限错误,如果我用chmod修复它,那么我会收到这个错误:

bash: ./myProgram.o: cannot execute binary file

我不知道该怎么办?

代码:

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct pixel {
    uint8_t r, g, b, a;
};

static uint8_t *load_image(char *filename, int *sizex, int *sizey)
{
    uint8_t *image;
    char buf[512];
    char *bufptr;
    int ret;

    FILE *fp = fopen(filename, "r");
    bufptr = fgets(buf, 512, fp);
    ret = fscanf(fp, "%d %d\n", sizex, sizey);
    bufptr = fgets(buf, 512, fp);

    image = malloc(*sizex * *sizey * 4);

    int i;
    uint8_t *ptr = image;
    for (i=0; i<*sizex * *sizey; ++i) {
        ret = fread(ptr, 1, 3, fp);
        ptr += 4;
    }

    fclose(fp);
    return image;
}

static int save_image(const char *filename, uint8_t *image, int sizex, int sizey)
{
    FILE *fp = fopen(filename, "w");
    fprintf(fp, "P6\n%d %d\n255\n", sizex, sizey);

    int i;
    uint8_t *ptr = image;
    for (i=0; i<sizex * sizey; ++i) {
        fwrite(ptr, 1, 3, fp);
        ptr += 4;
    }
    fclose(fp);

    return 1;
}

void convert_grayscale(uint8_t *input, uint8_t *output, int sizex, int sizey)
{
    // Y = 0.299 * R + 0.587 * G + 0.114 * B

    int i;

    for (i = 0; i < sizex * sizey; ++i)
        {
            struct pixel *pin = (struct pixel*) &input[i*4];
            struct pixel *pout = (struct pixel*) &output[i*4];

            float luma = 0.299 * pin->r + 0.587 * pin->g + 0.114 * pin->b;

            if (luma > 255)
                luma = 255;

            uint8_t intluma = (int) luma;

            pout->r = intluma;
            pout->g = intluma;
            pout->b = intluma;
            pout->a = 255;
        }

}

int main()
{
    uint8_t *inputimg, *outputimg;
    int sizex, sizey;

    inputimg = load_image("image.ppm", &sizex, &sizey);

    outputimg = malloc(sizex * sizey * 4);

    convert_grayscale(inputimg, outputimg, sizex, sizey);

    save_image("output.ppm", outputimg, sizex, sizey);
}

3 个答案:

答案 0 :(得分:2)

您的立即问题是C程序必须编译并链接。您的GCC调用使用-c选项,该选项告诉它只执行“编译”部分。尝试改为

gcc -g -Wall imgconvert.c -o imgconvert

然后

./imgconvert

我添加了一些新选项,-g表示生成调试信息,-Wall表示启用默认情况下应该打开的所有警告但不是。我没有详细查看你的代码,但很可能你会从第一个命令得到一些“警告:”消息,你应该修复它。

使用-c选项,你得到的是一个“对象”文件(这就是“.o”所代表的),它只能用作后续链接操作的输入。当你开始编写大于可以合理放在一个文件中的程序时,你会想要它。

顺便说一下,当你试图直接执行C源代码时得到的错误是因为,由于为了向后兼容而保留了古老的默认值,shell试图执行任何无法识别的编译可执行文件(文件开头的\177ELF或正确标记的解释脚本(文件开头的#! /path/to/interpreter),就像它是shell脚本一样。

答案 1 :(得分:1)

-c传递给gcc只会将源文件编译成目标文件。在构建可执行文件时,您应该省略它(以及“.o”后缀)。

答案 2 :(得分:1)

您已将程序编译为可执行文件。假设它只包含一个文件(imgconvert.c):

cc -o imgconvert imgconvert.c

然后你可以运行它:

./imgconvert