Julen, nice observation and suggestion, but as you indicate, across platforms there could be a problem
Will, thanks for that code and testing. Just before your reply, I was working with the Einhuger GraphicsFormat plugin and got some interesting result:
Dim pic as Picture
Dim jpg as JpegImporter
Dim c as Color
jpg = new JpegImporter
pic = jpg.OpenFromFile(GetFileAtRoot("j.jpg"))
if pic <> nil then
Canvas1.Backdrop = pic
end if
In this case the pixels reported back exactly what was shown in PS, for my test pixel. So what this does is read the data from disk bypassing Picture.Open and assigning the result to the picture object, and then drop it into the Canvas Backdrop
What I observed though was that the display colors were slight faded compared to if I just drop it into an ImageWell on Xojo, or if I viewed it under PhotoShop/Preview. I started worrying that when I add colors to this, say changes to some pixels through the Picture (g.DrawFill etc) what will happen.
I was contemplating the way forward when your suggestions came in. Interesting thet RGBSurface and the memoryblock differs
My major question at this stage was from your code you do the following:
Create a Xojo.Picture Drawing with ORANGE(255,128,64) color and save that as Orange.png
When you read it back, in console it was still ORANGE, but on the desktop it was say VividORANGE(251,129,63)
You then looked in the memoryblock of the picture an see it is still ORANGE
I did a few further experiments
I created a Orange.Png in Photoshop with RGB(255,128,64)
dim p as Picture = Picture.Open(SpecialFolder.Desktop.Child("Orange.png"))
p.Save(SpecialFolder.Desktop.Child("Orange1.png"), p.SaveAsPNG)
and then
dim p as Picture = Picture.Open(SpecialFolder.Desktop.Child("Orange1.png"))
p.Save(SpecialFolder.Desktop.Child("Orange2.png"), p.SaveAsPNG)
Now we are going to find some further interesting quirks:
In Photoshop Orange1 is RGB(252,106,50)
In Photoshop Orange2 os RGB(252,106,50)
If Xojo.Picture.Open is reading PNG created in Photoshop, it will change the RGB values if writing it out again. Orange vs Orange1
From this I can observe that if Xojo.Picture did the save, and it reads the file and save it again, it will stay the same RGB values. Orange1 vs Orange2
So I then did the same with JPG
Orange1 RGB(251,106,51)
Orange2 RGB(251,106,51)
This is rather interesting because it just shows that some translations are happening, and the translations have some rounding and possibly truncation somewhere because the translation works the same when executed a second time
BUT: If you read a non XOJO.Picture created file INTO picture, and then use the memoryblock RGB values, you will get the original values first time, but if you save it, you’ve lost the orginal values
I then started questioning what the Draw methods will do. So basically based on your Memoryblock findings I said:
Lets read the Original Photshop JPG file
Add two Ovals
Oval 1 should be same as the Original Photoshop RGB Orange value
Oval 2 should be the same as what you observed it changes to when read into Picture
dim p as Picture = Picture.Open(SpecialFolder.Desktop.Child("Orange.jpg"))
p.Graphics.ForeColor = RGB(255,128,64)
p.Graphics.FillOval(10,10,40,40) // oval 1
p.Graphics.ForeColor = RGB(251,106,51)
p.Graphics.FillOval(50,50,40,40) // oval 2
Canvas1.Backdrop = p
p.Save(SpecialFolder.Desktop.Child("Orange2_adjusted.jpg"), p.SaveAsJPEG)
The Orange2_Adjusted brings back values as follows:
Background and Oval2 RGB(251,106,51)
Oval1 RGB(255,128,64)
for those who wonder, these two sets of Orange are rather widely different when viewed on the screen!!
So I then did the same under a console App (just excluded the Canvas1.Backdrop
Results were:
Background and Oval1 RGB(255,128,64)
Oval2 RGB(251,106,51)
As expected! Eureka!
This console part is just interesting because it is equivalent to what will happen under a PC version of the app.
The problem I see is that if you read in an image created outside your App, and then saving it, it changes the colors. For now I assume this is relevant to Mac Desktop only. So if you mix from various sources, you get a change in result.
Just to test a bit further I did a read back in Xojo of the Orange.Jpg and Orange1.jpg and inspected using RGBSurface Pixel
dim p as Picture = Picture.Open(SpecialFolder.Desktop.Child("Orange.jpg"))
dim result as string
dim c as Color
c = p.RGBSurface.Pixel(1,1)
result = "Orange.jpg: RGB = " +c.Red.ToText + ", " + c.Green.ToText + ", " + c.Blue.ToText
p = Picture.Open(SpecialFolder.Desktop.Child("Orange1.jpg"))
c = p.RGBSurface.Pixel(1,1)
result = result + chr(10) + "Orange1.jpg: RGB = " +c.Red.ToText + ", " + c.Green.ToText + ", " + c.Blue.ToText
msgbox(result)
Results:
Orange.jpg RGB(252,106,51)
Orange1.jpg RGB(251,106,51)
Not sure where that extra 1 comes from either.
So I decided to use your XP Class and got the following back
Orange.jpg: XPicture RGB(255,128,65)
Orange1.jpg: XPicture RGB(254,128,65)
Not sure how that 1 jumped from the 255 to the 64, but it shows the memoryblock has values same to the original.
Here is the code for the XPicture versions
dim p as Picture = Picture.Open(SpecialFolder.Desktop.Child("Orange.jpg"))
dim result as string
dim c as Color
c = p.RGBSurface.Pixel(1,1)
result = "Orange.jpg: RGB = " +c.Red.ToText + ", " + c.Green.ToText + ", " + c.Blue.ToText
dim xp as new XPicture(p)
dim data as Ptr = xp.data
result = result + " - " + Str(data.UInt8(0)) + ", " + Str(data.UInt8(1)) + ", " + Str(data.UInt8(2))
p = Picture.Open(SpecialFolder.Desktop.Child("Orange1.jpg"))
c = p.RGBSurface.Pixel(1,1)
result = result + chr(10) + "Orange1.jpg: RGB = " +c.Red.ToText + ", " + c.Green.ToText + ", " + c.Blue.ToText
xp = new XPicture(p)
data = xp.data
result = result + " - " + Str(data.UInt8(0)) + ", " + Str(data.UInt8(1)) + ", " + Str(data.UInt8(2))
BUT wait, Photoshop reported RGB for Orange1.jpg as Orange1 RGB(251,106,51), whereas XPicture shows the data is still
Ok, so this is still not the end of this.
Orange.jpg was sRGB IEC61966-2.1 color profile
Orange1.jpg (generated by XOJO) was Generic RGB Profile
So it seems that XOJO when loading the picture must somehow check the color profile and adjust the underlying memoryblock pixels accordingly. So if sRGB then they get made a bit more Vivid for the display part, but stored as original. When Generic RGB, then it seems the memoryblock is scaled to less Vivid, while the display remains the same. This could explain the slight changes in the RGB codes from 64 to 65 and 255 to 254 etc.
I now need to go back and have a look at what Einhuger’s direct load does, because I suspect it ignores the Color Profile.
So It reads Orange.jpg as 255,128,65 and Orange1.jpg as 251,106,51.
This might seem different to what Will was seeing, but Will created the file with Xojo and Generic RGB to start with, and then read it back using Picture, and inspect the underlying memory block after the read. So this behavious was not apparent.
I now need to figure out what will happen under iOS. And I do not have a Pixel inspector for iOS, so lots more work to do teh testing there.
And now that I’ve found all this, I still need to understand how to work knowing all this.