2010-01-16 37 views
14

Tôi cần đọc một tập tin hình ảnh trong C/C++. Nó sẽ rất tuyệt vời, nếu một số người có thể đăng mã cho tôi.Đọc một tập tin hình ảnh trong C/C++

Tôi làm việc trên hình ảnh có thang màu xám và hình ảnh là JPEG. Tôi muốn đọc các hình ảnh thành một mảng 2D sẽ làm cho công việc của tôi dễ dàng.

Cảm ơn trước

+0

là tài liệu cho libjpeg (http://www.ijg.org/) hoặc bất cứ điều gì có nguồn gốc API bạn có đủ ? – greyfade

+1

Đừng quên chọn câu trả lời đúng cho ba câu hỏi bạn đã hỏi. – mwcz

Trả lời

2

Hãy thử thư viện CImg. tutorial sẽ giúp bạn làm quen. Khi bạn có đối tượng CImg, hàm data() sẽ cho phép bạn truy cập vào mảng đệm pixel 2D.

+0

Trên thực tế nó được mô hình hóa thành ma trận điểm ảnh 4D, mặc dù hình ảnh thang độ xám 2D sẽ có chiều sâu và kích thước màu được đặt thành 1. Dưới mui xe, nó là mảng 1D kiểu mẫu T. – jiggunjer

+0

Tôi tin rằng CImg yêu cầu libjpeg tải jpeg. –

12

Bạn có thể tự viết bằng cách xem JPEG format.

Điều đó nói rằng, hãy thử thư viện đã có từ trước như CImg hoặc Boost's GIL. Hoặc đối với định dạng JPEG, libjpeg. Ngoài ra còn có lớp CxImage trên CodeProject.

Đây là big list.

+1

Boost.GIL không hoạt động và không được duy trì. – Tronic

+1

Vì C được cho phép, tôi thứ hai libjpeg là giải pháp nhẹ nhất. CImg và GIL chắc chắn dễ dàng hơn về cú pháp - nhưng cũng yêu cầu libjpeg. Bạn có thể sao chép một cách trivially dữ liệu từ một đối tượng CImg vào một số container STL hoặc một mảng. – jiggunjer

+0

CImg cũng sử dụng giấy phép giống như LGPL, hạn chế đáng kể hơn giấy phép giống như BSD của libjpeg. – TypeIA

2

corona thật tuyệt. Từ hướng dẫn:

corona::Image* image = corona::OpenImage("img.jpg", corona::PF_R8G8B8A8); 
if (!image) { 
    // error! 
} 

int width = image->getWidth(); 
int height = image->getHeight(); 
void* pixels = image->getPixels(); 

// we're guaranteed that the first eight bits of every pixel is red, 
// the next eight bits is green, and so on... 
typedef unsigned char byte; 
byte* p = (byte*)pixels; 
for (int i = 0; i < width * height; ++i) { 
    byte red = *p++; 
    byte green = *p++; 
    byte blue = *p++; 
    byte alpha = *p++; 
} 

pixel sẽ là mảng một chiều, nhưng bạn có thể dễ dàng chuyển đổi vị trí x và y cho vị trí trong mảng 1D. Một cái gì đó như pos = (y * chiều rộng) + x

3

Check-out Intel mở CV thư viện ...

5

Nếu bạn quyết định sử dụng phương pháp tối thiểu, không có phụ thuộc libpng/libjpeg, tôi khuyên bạn nên sử dụng stb_imagestb_image_write, được tìm thấy here.

Nó đơn giản như vậy, bạn chỉ cần đặt các tệp tiêu đề stb_image.hstb_image_write.h trong thư mục của mình.

Dưới đây là đoạn code mà bạn cần phải đọc hình ảnh:

#include <stdint.h> 

#define STB_IMAGE_IMPLEMENTATION 
#include "stb_image.h" 

int main() { 
    int width, height, bpp; 

    uint8_t* rgb_image = stbi_load("image.png", &width, &height, &bpp, 3); 

    stbi_image_free(rgb_image); 

    return 0; 
} 

Và đây là đoạn code để viết một hình ảnh:

#include <stdint.h> 

#define STB_IMAGE_WRITE_IMPLEMENTATION 
#include "stb_image_write.h" 

#define CHANNEL_NUM 3 

int main() { 
    int width = 800; 
    int height = 800; 

    uint8_t* rgb_image; 
    rgb_image = malloc(width*height*CHANNEL_NUM); 

    // Write your code to populate rgb_image here 

    stbi_write_png("image.png", width, height, CHANNEL_NUM, rgb_image, width*CHANNEL_NUM); 

    return 0; 
} 

Bạn có thể biên dịch mà không cờ hoặc phụ thuộc:

g++ main.cpp 

Các lựa chọn thay thế nhẹ khác bao gồm:

+1

Tôi đã bao gồm các thư viện math.h và liên kết nó trong khi biên dịch (http://stackoverflow.com/questions/8671366/undefined-reference-to-pow-and-floor) hoặc tôi sẽ nhận được một tham chiếu không xác định để pow trong thư viện hình ảnh. –

+0

Tôi biết nó chỉ là một ví dụ nhưng bạn có thể làm rõ những gì ma thuật số 3 có nghĩa là trong mã? – mattshu

+1

@mattshu đó là số kênh (đỏ, lục, lam), có lẽ tôi nên làm rõ điều này trên mã của mình, tôi sẽ thực hiện chỉnh sửa. –

Các vấn đề liên quan