Ditransfer dari http://code.opencv.org/issues/1268
|| Richard Steffen on 2011-07-29 13:28
|| Priority: Low
|| Affected: None
|| Category: highgui-images
|| Tracker: Feature
|| Difficulty:
|| PR:
|| Platform: None / None
Currently, the imread and imwrite method only supports std::string as an input. This isn't working with non-ascii directories/paths. Therefore, the a software depends on OpenCV can not guaranty working on all maschines.
- Description changed from Currently, the imread and imwrite method
only supports std::string as an inpu... to Currently, the imread and
imwrite method only supports std::string as an inpu... More
std::string is still capable of storing any unicode name via UTF-8 encoding, and so it's fopen responsibility to handle this UTF-8 name properly. On Mac and Linux I was able to store image into a file with non-ASCII letters using normal cv::imwrite(). I guess, on Windows it will work too, if you save a source file to UTF-8.
- Priority changed from High to Low
- Assignee set to Vadim Pisarevsky
- Status changed from Open to Cancelled
- Target version set to 2.4.0
AFAIK fopen does not support Unicode on Windows and can't be used to open a path with Unicode characters. The UTF-8 string must be converted to UTF-16 and given to _wfopen instead. See ImageMagick's fopen_utf8 wrapper for example code: http://www.imagemagick.org/api/MagickCore/utility-private_8h_source.html#l00103
- Target version changed from 2.4.0 to 2.4.9
- Status changed from Cancelled to Open
One possible workaround for now using Boost and a memory mapped file:
mapped_file map(path(L"filename"), ios::in);
Mat file(1, numeric_cast<int>(map.size()), CV_8S, const_cast<char*>(map.const_data()), CV_AUTOSTEP);
Mat image(imdecode(file, 1));
The downside is that I/O errors cause access violations instead of C++ exceptions. Also don't write to the "file" Mat. :)
Unfortunately the trick of avoiding to store the image file in memory doesn't work with imwrite, as imencode stores the output in a vector with standard allocator specified. If memory is no issue the contents can of course be written to file using Boost afterwards.
- Target version changed from 2.4.9 to 3.0
IMHO ini harus ditentukan dalam dokumentasi: di sini http://docs.opencv.org/master/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56 dan di sini http://docs.opencv.org/master/d4/da8/group__imgcodecs .html#gabbc7ef1aa2edfaa87772f1202d67e0ce.
Masalah pengkodean .... sulit tetapi bukan tidak mungkin
jika Anda memiliki string ini = 'テスト/abc.jpg'
Anda dapat menyandikan sebagai Windows yang menyandikan karakter seperti ini ->
print('テスト/abc.jpg'.encode('utf-8').decode('unicode-escape'))
Dan Anda mendapatkan sesuatu seperti ini = 'ãã¹ã/abc.jpg'
Kemudian jika Anda ingin membaca file dan membuat nama file dapat dibaca dan digunakan, Anda dapat menggunakan beberapa perpustakaan untuk membaca nama file jalur Anda dan kemudian mengubah penyandian ->
#fname is like 'ãã¹ã/abc.jpg'
fname.encode('iso-8859-1').decode('utf-8')) # Ini hasil string awal Anda = 'テスト/abc.jpg'
Tim inti OpenCV membahas masalah tersebut pada pertemuan mingguan dan memutuskan untuk tetap konservatif dan tidak memperkenalkan panggilan API baru dengan wchar_t
, wstring
dan tipe string lainnya Dengan alasan berikut:
fopen
standar untuk membuka file dan dukungan wchar_t
tambahan memerlukan modifikasi pustaka domainstd::string
sebagai wadah untuk meneruskannya ke fungsi OpenCV.wchar_t
secara native dan kelebihan beban bukanlah solusi lintas platform.Ada 2 alternatif untuk menggunakan string wchar_t
dengan OpenCV:
Ubah string wchar_t
menjadi UTF-8 dan teruskan string UTF-8 sebagai parameter cv::imread
dan cv::imwrite
. String UTF-8 ditangani oleh panggilan sistem fopen
dan perilakunya tergantung pada dukungan OS dan lokal. Lihat mbstowcs
dalam standar C++ untuk lebih jelasnya.
OpenCV menyediakan fungsi cv::imdecode
dan cv::imencode
yang memungkinkan untuk mendekode dan mengkodekan gambar menggunakan buffer memori sebagai input dan output. Solusinya memisahkan file IO dan decoding gambar dan memungkinkan untuk mengelola string jalur, lokal, dll dalam kode pengguna. Lihat cuplikan kode untuk cv::imencode
di bawah. fopen
dapat diganti dengan _wfopen
untuk dukungan string lebar. Lihat manual referensi Microsoft untuk detailnya: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=vs-2019
#include <vector>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
int main(int argc, char ** argv)
{
FILE* f = fopen("lena.jpg", "rb");
fseek(f, 0, SEEK_END); // seek to end of file
size_t buffer_size = ftell(f); // get current file pointer
fseek(f, 0, SEEK_SET); // seek back to beginning of file
std::vector<char> buffer(buffer_size);
fread(&buffer[0], sizeof(char), buffer_size, f);
fclose(f);
cv::Mat frame = cv::imdecode(buffer, cv::IMREAD_COLOR);
cv::imshow("Camera", frame);
cv::waitKey();
}
Komentar yang paling membantu
IMHO ini harus ditentukan dalam dokumentasi: di sini http://docs.opencv.org/master/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56 dan di sini http://docs.opencv.org/master/d4/da8/group__imgcodecs .html#gabbc7ef1aa2edfaa87772f1202d67e0ce.