Closed kyushu closed 1 year ago
You should not make base64 encode for image. You have to send it as is (it is requirements if HTTP protocol). Code looks correct, except you need assign img to body directly: std::string body(static_cast<char*>(img), length_of_img_data ); You need only to provide the length of data. strlen should not be used, as img data can contain \0 char inside. By the way, drogon has build in function to download jpeg file, if they are in root folder (root folder assigned in settings file).
You should not make base64 encode for image. You have to send it as is (it is requirements if HTTP protocol). Code looks correct, except you need assign img to body directly: std::string body(static_cast<char*>(img), length_of_img_data ); You need only to provide the length of data. strlen should not be used, as img data can contain \0 char inside. By the way, drogon has build in function to download jpeg file, if they are in root folder (root folder assigned in settings file).
Thanks for response so quick
I've tried your way to set body but still can't get correct result, i post my controller header/cpp and the error message on web browser
could you point me out what is wrong ? Thanks !
in header
#pragma once
#include <drogon/HttpController.h>
using namespace drogon;
class ImageCtrl : public drogon::HttpController<ImageCtrl>
{
public:
METHOD_LIST_BEGIN
ADD_METHOD_VIA_REGEX(ImageCtrl::handle_image, "/images/.*", Get);
METHOD_LIST_END
void handle_image(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback) const;
};
in cpp
void ImageCtrl::handle_image(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback) const
{
std::string path = req->getPath();
std::cout << "path: " << path << std::endl;
int width, height, channels;
unsigned char *img = stbi_load("/test_result/images/a11/test_01.jpg", &width, &height, &channels, 0);
std::string body(reinterpret_cast<char*>(img), width*height*channels);
auto resp = HttpResponse::newHttpResponse();
resp->setStatusCode(k200OK);
resp->setContentTypeCode(CT_IMAGE_JPG);
resp->setBody(body);
callback(resp);
}
in web browser it shows : The image "http://localhost/images/" cannot be displayed because it contains errors.
Your Drogon controller is correct, it sends data to browser, the browser reads them, understands, that it is image , but does no understand image format. The problem is with data. If you send JPEG, you have to read JPEG file (fstream open(), read(), close()) and send these data to controller in a body. If you load image, you sends not JPEG, you send pixels as data.
Try use HttpResponse::newFileResponse()
. Search this api in source code and you will find some example codes.
Try use
HttpResponse::newFileResponse()
. Search this api in source code and you will find some example codes.
@VladlenPopolitov , @hwc0919 Thanks !
I use HttpResponse::newFileResponse() and it works
In case anyone who is same as me new to web backend development, here is my summary:
for my case, here is an example code:
std::string file_path = "/test_result/images/a11/test_01.jpg";
auto resp = HttpResponse::newFileResponse(file_path, "", CT_IMAGE_JPG);
Hi, i want to build a image file server, but i don't know how to response image
i have tried the following code in controller but it does not work
could you write an example for me?