FCT
载入中...
搜索中...
未找到
FreeImage_ImageLoader.cpp
浏览该文件的文档.
2
3#include <iostream>
4#include <stdexcept>
5
6namespace FCT {
8 {
9 FreeImage_Initialise();
10 FreeImage_SetOutputMessage(freeImageErrorHandler);
11 }
13 {
14 FreeImage_DeInitialise();
15 }
18
21
22 ImageLoader::ImageData FreeImage_ImageLoader::loadFromMemory(const unsigned char* data, size_t size) {
23 FIMEMORY* hmem = FreeImage_OpenMemory((BYTE*)data, size);
24 if (hmem == nullptr) {
25 throw std::runtime_error("Could not open memory stream for image");
26 }
27
28 FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(hmem, 0);
29 if (fif == FIF_UNKNOWN) {
30 FreeImage_CloseMemory(hmem);
31 throw std::runtime_error("Unknown image format from memory");
32 }
33
34 FIBITMAP* dib = FreeImage_LoadFromMemory(fif, hmem, 0);
35 FreeImage_CloseMemory(hmem); // Memory handle can be closed after loading
36
37 if (!dib) {
38 throw std::runtime_error("Failed to load image from memory");
39 }
40
41 FIBITMAP* dibConverted = FreeImage_ConvertTo32Bits(dib);
42 FreeImage_Unload(dib);
43
44 if (!dibConverted) {
45 throw std::runtime_error("Failed to convert image to 32 bits");
46 }
47
48 ImageData imageData;
49 imageData.width = FreeImage_GetWidth(dibConverted);
50 imageData.height = FreeImage_GetHeight(dibConverted);
51 imageData.channels = 4; // RGBA
52
53 unsigned int pitch = FreeImage_GetPitch(dibConverted);
54 imageData.data.resize(imageData.height * pitch);
55
56 FreeImage_ConvertToRawBits(imageData.data.data(), dibConverted, pitch, 32,
57 FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE);
58
59 // FreeImage loads images as BGRA, so we need to swap Red and Blue channels to get RGBA.
60 for (unsigned int y = 0; y < imageData.height; ++y) {
61 for (unsigned int x = 0; x < imageData.width; ++x) {
62 unsigned int offset = (y * pitch) + (x * 4);
63 std::swap(imageData.data[offset], imageData.data[offset + 2]);
64 }
65 }
66
67 FreeImage_Unload(dibConverted);
68
69 return imageData;
70 }
71
72
74 FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(filename.c_str(), 0);
75 if (fif == FIF_UNKNOWN) {
76 fif = FreeImage_GetFIFFromFilename(filename.c_str());
77 }
78
79 if (fif == FIF_UNKNOWN) {
80 throw std::runtime_error("Unknown image format");
81 }
82
83 FIBITMAP* dib = FreeImage_Load(fif, filename.c_str());
84 if (!dib) {
85 throw std::runtime_error("Failed to load image");
86 }
87
88 FIBITMAP* dibConverted = FreeImage_ConvertTo32Bits(dib);
89 FreeImage_Unload(dib);
90
91 if (!dibConverted) {
92 throw std::runtime_error("Failed to convert image to 32 bits");
93 }
94
95 ImageData imageData;
96 imageData.width = FreeImage_GetWidth(dibConverted);
97 imageData.height = FreeImage_GetHeight(dibConverted);
98 imageData.channels = 4; // RGBA
99
100 unsigned int pitch = FreeImage_GetPitch(dibConverted);
101 imageData.data.resize(imageData.height * pitch);
102
103 FreeImage_ConvertToRawBits(imageData.data.data(), dibConverted, pitch, 32,
104 FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE);
105
106 for (unsigned int y = 0; y < imageData.height; ++y) {
107 for (unsigned int x = 0; x < imageData.width; ++x) {
108 unsigned int offset = (y * pitch) + (x * 4);
109 std::swap(imageData.data[offset], imageData.data[offset + 2]);
110 }
111 }
112
113
114 FreeImage_Unload(dibConverted);
115
116 return imageData;
117 }
118
119 bool FreeImage_ImageLoader::save(const std::string& filename, const ImageData& imageData) {
120 FIBITMAP* dib = FreeImage_AllocateT(FIT_BITMAP, imageData.width, imageData.height, 32);
121 if (!dib) {
122 return false;
123 }
124
125 unsigned int pitch = FreeImage_GetPitch(dib);
126 FreeImage_ConvertFromRawBits(
127 (BYTE*)imageData.data.data(),
128 imageData.width,
129 imageData.height,
130 pitch,
131 32,
132 FI_RGBA_RED_MASK,
133 FI_RGBA_GREEN_MASK,
134 FI_RGBA_BLUE_MASK
135 );
136
137 FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(filename.c_str());
138 bool success = FreeImage_Save(fif, dib, filename.c_str());
139
140 FreeImage_Unload(dib);
141
142 return success;
143 }
144
145 std::vector<std::string> FreeImage_ImageLoader::getSupportedExtensions() const {
146 return {".bmp", ".png", ".jpg", ".jpeg", ".tif", ".tiff"}; // Add more as needed
147 }
148
149 void FreeImage_ImageLoader::freeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) {
150 std::cerr << "FreeImage error: ";
151 if (fif != FIF_UNKNOWN) {
152 std::cerr << FreeImage_GetFormatFromFIF(fif) << " Format - ";
153 }
154 std::cerr << message << std::endl;
155 }
156
157} // namespace FCT
static void freeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message)
bool save(const std::string &filename, const ImageData &imageData) override
ImageLoader::ImageData loadFromMemory(const unsigned char *data, size_t size) override
std::vector< std::string > getSupportedExtensions() const override
ImageData load(const std::string &filename) override
std::vector< unsigned char > data