Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to load PNG images with "resolution" data embedded depends on OS "formats" setting #1515

Open
DarkFenX opened this issue Feb 12, 2020 · 24 comments

Comments

@DarkFenX
Copy link

DarkFenX commented Feb 12, 2020

Operating system: Windows 8.1, windows 10
wxPython version & source: 4.0.7post2 from pip
Python version & source: python 3.8.1

Description of the problem:

if __name__ == '__main__':
    app = wx.App(False)
    img = wx.Image('imgs/gui/fighter_small.png')

Image itself: https://github.com/pyfa-org/Pyfa/blob/b15f9766c121b331bae1be0b07b3b231b85a624d/imgs/gui/fighter_small.png

Repro steps:

  1. Open Windows CP's regional settings, set "format" field to English (Singaporean) for win 8.1, or English (European) for win 10 (as examples which i tested myself)
  2. Execute attached script

Result:

E:\eve\pyfa>C:\Python38_64\python.exe wxtest.py
Traceback (most recent call last):
  File "wxtest.py", line 61, in <module>
    img = wx.Image('imgs/gui/fighter_small.png')
wx._core.wxAssertionError: C++ assertion "strcmp(setlocale(LC_ALL, NULL), "C") =
= 0" failed at ..\..\src\common\intl.cpp(1579) in wxLocale::GetInfo(): You proba
bly called setlocale() directly instead of using wxLocale and now there is a mis
match between C/C++ and Windows locale.
Things are going to break, please only change locale by creating wxLocale object
s to avoid this!

If i set format to English (US), it loads

Expected: image is loaded.

@DarkFenX
Copy link
Author

DarkFenX commented Feb 12, 2020

wxpython 4.0.6 + python 3.7 seem not to have this issue (i failed to build wx 4.0.6 for python 3.8)

@Metallicow
Copy link
Contributor

Metallicow commented Feb 12, 2020

This type of trace has popped up before with other users. No one really knows fully, but optimizing the image sometimes works. Try that first. Also if you need to wrap your path with abspath, do so. If that don't work jump on the bandwagon and search the other issues for your maybe solution...

Optimized image:
fighter_small

@DarkFenX
Copy link
Author

DarkFenX commented Feb 12, 2020

I decided just to downgrade to 4.0.6 for now (to fix this issue and #1008). If 1008 gets fixed, i might consider batch-converting the images.

@Metallicow
Copy link
Contributor

I really haven't any idea because the locales thing doesn't effect me, just the iccp incorrect srgb profile warning sometimes which optimizing fixes,... but just to throw some wild ideas out there, has anyone considered that the images might have been saved with pirated software or something? Even open-source Gimpshop fork at one point had bundled crapware in its installer...
https://en.wikipedia.org/wiki/Steganography is a neat idea to toy with but you can do some strange things if someone really tried to target something. Or maybe your OS is either missing a language pack or has one it doesn't like for some odd reason.

If I where you, I'd investigate more specifically the operating system stuff. Downgrading isn't a fix, just a temporary workaround, unless your downgrading to Win7 which just retired along with py27. Maybe if the users that are having these issues provided more specifics about other things and or talked with one another, might come up with a common thing amongs't them.

@DarkFenX
Copy link
Author

I was able to replicate the issue myself. It's definitely the "Format" setting affecting it.

Don't get me wrong, downgrading is a sub-par solution to me in general. If it was only this issue i'd look into repackaging the images. However, inconsistent behavior bothers me (with "English (US)" wx takes "wrong" image just fine, with "English (European)" it does not), and 4.0.7post2 has another regression which repackaged images do not fix. On top of that. 4.0.7post2 doesn't contain any changes which would be interesting for my app, so reverting to 4.0.6 is a no-brainer.

@cbeytas
Copy link
Contributor

cbeytas commented Feb 13, 2020

What if you create a locale just after you create the App?

locale = wx.Locale(wx.LANGUAGE_DEFAULT)

I've had to put this workaround in all my wx applications (with wx 2.9 or later) otherwise they'll throw that same exception. Never had this issue with wx 2.8

@DarkFenX DarkFenX changed the title Ability to load specific images depends on OS format Ability to load specific images depends on OS "formats" setting Feb 13, 2020
@DarkFenX
Copy link
Author

@cbeytas do I need to set to app/wx somehow? Just initializing it does not help.

@DarkFenX
Copy link
Author

DarkFenX commented Feb 13, 2020

I just realized that when I added app.ResetLocale() I've ran exactly into this issue. If converting images + resetlocale will work, I will stay on 4.0.7post2 i guess.

has anyone considered that the images might have been saved with pirated software or something

Just wanted to comment on that - this is defintely not the case, first images I reexported with gimp is still broken.

@DarkFenX
Copy link
Author

DarkFenX commented Feb 13, 2020

GIMP export settings:

image

The issue goes away if i re-export image with "Save resolution" option disabled

@DarkFenX
Copy link
Author

DarkFenX commented Feb 13, 2020

I removed resolution from all offending images in my app, but still have issues. Below is example of another manifestation, apparently wx built-in bitmaps also suffer from this issue:

if __name__ == '__main__':
    app = wx.App(False)
    app.ResetLocale()
    img = wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE_AS, wx.ART_BUTTON)

app.ResetLocale() leads to the same behavior as setting "Format" setting to "English (Singaporean)", so could just use it here as well.

I tested 5 built-in images, 4 of them are "broken":

  • ART_NEW
  • ART_COPY
  • ART_FILE_OPEN
  • ART_FILE_SAVE_AS

One of them loaded just fine:

  • ART_DELETE

So, i guess, rolling back is a way to go.

@Metallicow
Copy link
Contributor

@DarkFenX I optimized your repo images, to see if that might help you. Had to run the optimizer overnight since you have so many images in the repo. Saved about 10% in bytes at max, so wait until I send a pull reqz before testing again. Might take a few hours...

@Metallicow
Copy link
Contributor

Note that image manipulation applications do not optimize images, but usually attach a profile by default. I see that gimp has that option to not attach a profile. Photoshop used to do the same thing. IIRC krita has an option for not attaching a profile also. This should be default behavior if you are saving images for embedding or wx with whatever version of libPNG causes the issues.

@DarkFenX
Copy link
Author

DarkFenX commented Apr 24, 2020

FYI this is still an issue for my app. My current solution was rolling back to python 3.7 + wxpython 4.0.6, but a few days ago I've got a report that app fails to launch on some "Format" settings too: pyfa-org/Pyfa#2174

Correct solution would be to upgrade to 3.8 + 4.0.7post2 + reset locale, but then I run into this issue which leads to crash in some parts of my app, no matter the system settings. So, for the love of god please remove resolution metadata from wx built-in images (or optimize them, whatever it does) and make another bugfix wx release with fixed images.

Or maybe suggest some way to work around it, which is not very obvious to me.

@Metallicow
Copy link
Contributor

@DarkFenX Do you mean the pyEmbeddedImages? Do you know which ones are causing the problems? Specifics would help. I've optimized some of them in the past. I don't recall Ive done them all. The famfamfam flags iirc didnt get finished...
The process involves saving the embedded images back to a png, running them thru the optimizer then using png2img on them again and write the new optimized embedeed code in whatever module.

@DarkFenX
Copy link
Author

I know wx image codes which screw it up for me, but not actual image files, sorry. More on that in the comment: #1515 (comment)

@Metallicow
Copy link
Contributor

ummmm. those are probably at the wxWidgets level or operating system snagged images.... I haven't even looked into those.
@RobinD42 any suggestions? Where would these be located?
stuff like wx.ART_NEW

@Metallicow
Copy link
Contributor

I folks want to work on creating a PyArtProvider that would probably work, but having source images would be needed and figure out what to make as an image for each code. Andrea had some crystal images for he used for one of his dialog modules. Something along those lines...

from wx.lib.PyArtProvider import ArtProvider as PyArtProvider
img = PyArtProvider.GetBitmap(wx.ART_FILE_SAVE_AS, wx.ART_BUTTON)

I think something like this would work if other images are os images that cant be optimized(Ex: they might come from a DLL or something...)

@Metallicow
Copy link
Contributor

If you are getting the `iCCP: known incorrect sRGB profile' warning
try this

class MyApp(wx.App):
    """"""
    def OnInit(self):
        """"""
        # wx.Log.EnableLogging(enable=False)  wxPy 4.0 and before
        wx.Image.SetDefaultLoadFlags(0)  # wxPy 4.

This works with wxpy4.1

class MyPanel(wx.Panel):
    """"""
    def __init__(self, parent, id=wx.ID_ANY,
                 pos=wx.DefaultPosition, size=wx.DefaultSize,
                 style=wx.BORDER_SUNKEN, name='panel'):
        """"""
        wx.Panel.__init__(self, parent, id, pos, size, style, name)

        image = wx.Image()
        image.SetLoadFlags(0)
        image.LoadFile('iCCP_known_incorrect_sRGB_profile.png')
        wx.StaticBitmap(self, -1, wx.Bitmap(image))

@DarkFenX
Copy link
Author

DarkFenX commented Apr 25, 2020

Python 3.8.2, wxpython 4.0.7post2, with the example I linked above (with wx.ART_FILE_SAVE_AS) I am still getting this error (not iCCP: known incorrect sRGB profile error):

Traceback (most recent call last):
  File "wxtest.py", line 6, in <module>
    img = wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE_AS, wx.ART_BUTTON)
wx._core.wxAssertionError: C++ assertion "strcmp(setlocale(LC_ALL, NULL), "C") == 0" failed at ..\..\src\common\intl.cpp(1579) in wxLocale::GetInfo(): You probably called setlocale() directly instead of using wxLocale and now there is a mismatch between C/C++ and Windows locale.
Things are going to break, please only change locale by creating wxLocale objects to avoid this!

After I modified the code to following:

import wx

class MyApp(wx.App):
    """"""
    def OnInit(self):
        """"""
        wx.Image.SetDefaultLoadFlags(0)  # wxPy 4.
        return True


if __name__ == '__main__':
    app = MyApp(False)
    app.ResetLocale()
    img = wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE_AS, wx.ART_BUTTON)

It breaks on setting flags:

Traceback (most recent call last):
  File "wxtest.py", line 8, in OnInit
    wx.Image.SetDefaultLoadFlags(0)  # wxPy 4.
AttributeError: type object 'Image' has no attribute 'SetDefaultLoadFlags'
OnInit returned false, exiting...

Just realized that 4.1 is released, going to give it a try.

@DarkFenX
Copy link
Author

DarkFenX commented Apr 25, 2020

python 3.8.2, wxpython 4.1.0, i get the same result with basic example I provided (the You probably called setlocale() directly instead of using wxLocale and now there is a mismatch between C/C++ and Windows locale. error).

edit: just to clarify: it happens not just when I reset locale in my code, it also happens if I set system format to singaporean english as well (as mentioned in original report).

@Metallicow
Copy link
Contributor

@DarkFenX @RobinD42 Ok I finally managed to get the error playing around for a bit.

import wx

class MyApp(wx.App):
    """"""
    def OnInit(self):
        """"""
        # un/comment out line as necessary
        # wx.Image.SetDefaultLoadFlags(0)  # wxPy 4.1
        return True


if __name__ == '__main__':
    print(wx.version())
    app = MyApp(False)
    app.ResetLocale()
    img = wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE_AS, wx.ART_BUTTON)
    print(img)

...Using singapore english did not matter. Using Python 3.8 did. Apparently Win7 Ultimate doesn't matter either.

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\test\Desktop>py -3 tmpRun.py
4.0.7.post2 msw (phoenix) wxWidgets 3.0.5
Traceback (most recent call last):
  File "tmpRun.py", line 7, in OnInit
    wx.Image.SetDefaultLoadFlags(0)  # wxPy 4.1
AttributeError: type object 'Image' has no attribute 'SetDefaultLoadFlags'
OnInit returned false, exiting...

C:\Users\test\Desktop>py -3 tmpRun.py
4.0.7.post2 msw (phoenix) wxWidgets 3.0.5
Traceback (most recent call last):
  File "tmpRun.py", line 15, in <module>
    img = wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE_AS, wx.ART_BUTTON)
wx._core.wxAssertionError: C++ assertion "strcmp(setlocale(LC_ALL, NULL), "C") =
= 0" failed at ..\..\src\common\intl.cpp(1579) in wxLocale::GetInfo(): You proba
bly called setlocale() directly instead of using wxLocale and now there is a mis
match between C/C++ and Windows locale.
Things are going to break, please only change locale by creating wxLocale object
s to avoid this!

C:\Users\test\Desktop>py -2 tmpRun.py
4.1.0a1.dev4686+5be2356b msw (phoenix) wxWidgets 3.1.4
<wx._core.Bitmap object at 0x023C2DA0>

C:\Users\test\Desktop>

@DarkFenX
Copy link
Author

@Metallicow how would you advise to work around it? By avoiding python 3.8?

@Metallicow
Copy link
Contributor

idunno. Ask/Wait for Robin to reply and in the meantime find a Python that doesn't produce the error.
Kinda strange cause SourceCoder works just fine. Only issue I have on startup now with Py3.8 is a ListCtrl fails out creation when it comes to images....(but a different append method works tho!?!) It has a custom exceptionHook to catch all that stuff tho so I don't totally crash at startup. And I cant seem to reproduce it in the demo atm, so no I havent made a report ticket.

@DarkFenX DarkFenX changed the title Ability to load specific images depends on OS "formats" setting Ability to load PNG images with "resolution" data embedded depends on OS "formats" setting Apr 27, 2020
@swt2c
Copy link
Collaborator

swt2c commented Jul 15, 2020

There will be a new version of InitLocale() in wxPython 4.1.1. that might fix this issue. Can you try one of the latest snapshots to see? https://wxpython.org/Phoenix/snapshot-builds/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants