1

Hi i am trying to make a GUI for image compare software. The idea is to choose a picture with OPENFILENAME, then get its address with ofn.lpstrFile then make a histogram for that image. So i use:

return(ofn.lpstrFile);

I can cout the address or write it to an .xml file and the address is correct, but when i am trying to do the histogram it gives me all zeros. Behaves like the address was invalid.

Any ideas ?

my code :

    string path=browse(); //getting the string from ofn.lpstrFile

    path.c_str();
    replace(path.begin(), path.end(), '\\', '/'); //converting backslash to slash also may be the problem       
    HistCreation(path,root_dir); 

and

void HistCreation(string path,string root_dir) {

Mat img;
img = imread(path); // here if i manually enter the address everything works fine, if I insert the path then loads empty image

.
.
.

I also tried

char * cstr = new char[path.length() + 1];
    std::strcpy(cstr, path.c_str());

Did not work either

Viktor Bendik
  • 97
  • 3
  • 11
  • 2
    Use `std::wstring` for returning strings. Returning pointers is a bad idea if you don't know what you are doing. – Barmak Shemirani Aug 04 '16 at 17:56
  • You're not trying to do a histogram of the *file name*, are you? – molbdnilo Aug 04 '16 at 18:00
  • Thanks for the response!. @BarmakShemirani I tryed to { wstring path=ofn.lpstrFile } but it says: no suitable constructor to convert from LPSTR to string,wchar,char,wchar_t can you be more specific please? – Viktor Bendik Aug 04 '16 at 18:22
  • @molbdnilo I am just trying to read the image by the address got from openfiledialog . Then make the histogram of the picture which is on that address – Viktor Bendik Aug 04 '16 at 18:23
  • @ViktorBendik There's no picture at the address `ofn.lpstrFile`, that's a pointer to the file name. – molbdnilo Aug 04 '16 at 18:26
  • I thought you are using Unicode. Use `std::string path = ofn.lpstrFile;`, return `path`, then `path.c_str()` is the file name. You have to open that filename with graphics library such as GDI+ – Barmak Shemirani Aug 04 '16 at 18:34
  • @molbdnilo okay but how can i get to that file name ? I can save ofn.lpstrFile to a string and then cout it ... but somehow if i use that string to imread it loads me an empty nothing – Viktor Bendik Aug 04 '16 at 18:38
  • @BarmakShemirani Yep i switched character set from Unicode to not set. Tryed the `path.c_str()` nothing happened , still loads an empty image. Maybe the problem is with the transformation from backslash to normal slash i really dont know. – Viktor Bendik Aug 04 '16 at 19:31

1 Answers1

1

std::string returns the string and that's all you need. This is example to open a bitmap file.

(Edit)

#include <iostream>
#include <string>
#include <windows.h>

std::string browse(HWND hwnd)
{
    std::string path(MAX_PATH, '\0');
    OPENFILENAME ofn = { sizeof(OPENFILENAME) };
    ofn.hwndOwner = hwnd;
    ofn.lpstrFilter = 
        "Image files (*.jpg;*.png;*.bmp)\0*.jpg;*.png;*.bmp\0"
        "All files\0*.*\0";
    ofn.lpstrFile = &path[0];
    ofn.nMaxFile = MAX_PATH;
    ofn.Flags = OFN_FILEMUSTEXIST;
    if (GetOpenFileName(&ofn))
    {
        //string::size() is still MAX_PATH
        //strlen is the actual string size (not including the null-terminator)
        //update size:
        path.resize(strlen(path.c_str()));
    }
    return path;
}

int main()
{
    std::string path = browse(0);
    int len = strlen(path.c_str());
    if (len)
        std::cout << path.c_str() << "\n";
    return 0;
}

Note, Windows uses NUL-terminated C-strings. It knows the length of the string by looking for the zero at the end.

std::string::size() is not always the same thing. We can call resize to make sure they are the same thing.


You shouldn't need to replace \\ with /. If your library complains about \\ then replace as follows:

Example:

...
#include <algorithm>
...
std::replace(path.begin(), path.end(), '\\', '/');

Use std::cout to examine the output instead of guessing if it worked or not. In Windows program you can use OutputDebugString or MessageBox to see what the string is.

HistCreation(path, root_dir);

I don't know what root_dir is supposed to be. If HistCreation fails or it has the wrong parameter then you have a different problem.

Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • Awesome! @BarmakShemirani with some changes i got to work now. Thanks a lot i was working on this the whole day. I will edit your post to the form i have now to make the answer more accurate. Nice job man thank you! – Viktor Bendik Aug 04 '16 at 20:36
  • I commented out some of your suggested edit. `path.erase(path.begin() + a, path.end());` doesn't do anything. The string is fine as is. – Barmak Shemirani Aug 04 '16 at 20:57
  • strange .... if i print out the path i see something like this: C:/path/dir/image.jpgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa . thats why i used that earse – Viktor Bendik Aug 05 '16 at 11:21
  • Can you tell me what is your compiler and version number, and also your Windows version? See updated answer. `string::size()` is not the same thing as `strlen(path.c_str())`. – Barmak Shemirani Aug 05 '16 at 16:01