Hello
What is a good modern way in Squeak to load a picture from the web?
I am looking for an equivalent of
| pngPicURL aStream |
pngPicURL := 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...'.
aStream := HTTPSocket httpGet: pngPicURL.
(ImageReadWriter formFromStream: aStream) asMorph openInHand
And answer or just comments are welcome.
Thank you.
Kind regards
Hannes
What about ...
Form fromBinaryStream: (WebClient httpGet: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...') contentStream.
... I think we should add a #fromUrl: besides Form class >> #fromFileNamed: and there distinguish between file paths and HTTP urls etc:
Form fromUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...'.
Best, Marcel Am 21.03.2019 11:51:58 schrieb H. Hirzel hannes.hirzel@gmail.com: Hello
What is a good modern way in Squeak to load a picture from the web?
I am looking for an equivalent of
| pngPicURL aStream |
pngPicURL := 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...'.
aStream := HTTPSocket httpGet: pngPicURL.
(ImageReadWriter formFromStream: aStream) asMorph openInHand
And answer or just comments are welcome.
Thank you.
Kind regards
Hannes
Thanks for answering, Marcel
On 3/21/19, Marcel Taeumel marcel.taeumel@hpi.de wrote:
What about ...
Form fromBinaryStream: (WebClient httpGet: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...') contentStream.
Unfortunately a debugger window comes up [1]
... I think we should add a #fromUrl: besides Form class >> #fromFileNamed: and there distinguish between file paths and HTTP urls etc:
Form fromUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...'.
Yes, that would be fine to create a new convenience method
Form fromUrl:
after we have figured out the solution.
-- Hannes
[1] SecureSocketStream(Object)>>doesNotUnderstand: #reset Receiver: SecureSocketStream[inbuf:4kb/outbuf:4kb] Arguments and temporary variables: aMessage: reset exception: MessageNotUnderstood: SecureSocketStream>>reset resumeValue: nil Receiver's instance variables: recentlyRead: 0 socket: a Socket[destroyed] inBuffer: #[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0...etc... outBuffer: #[71 69 84 32 47 119 105 107 105 112 101 100 105 97 47 99 111 109 10...etc... inNextToWrite: 1 outNextToWrite: 1 lastRead: 0 timeout: 45 autoFlush: true bufferSize: 4096 binary: true shouldSignal: true ssl: nil sendBuf: #[23 3 3 0 232 61 247 6 24 144 238 146 249 51 100 82 127 29 104 195 17...etc... readBuf: #[203 4 102 97 151 46 237 173 196 165 168 136 21 56 21 225 6 113 183 1...etc... decoded: a ReadStream certIssues: 0
[] in ImageReadWriter class>>formFromStream: Receiver: ImageReadWriter Arguments and temporary variables: <<error during printing> Receiver's instance variables: superclass: Object methodDict: a MethodDictionary(#atEnd->(ImageReadWriter>>#atEnd "a CompiledMethod...etc... format: 65537 instanceVariables: #('stream') organization: ('accessing' nextImage nextPutImage:) ('stream access' atEnd close...etc... subclasses: {PCXReadWriter . XBMReadWriter . JPEGReadWriter . JPEGReadWriter2 ....etc... name: #ImageReadWriter classPool: a Dictionary(#ImageNotStoredSignal->nil #MagicNumberErrorSignal->nil...etc... sharedPools: nil environment: nil category: #'Graphics-Files'
It works if I replace
#contentStream
with
content asByteArray readStream
Form fromBinaryStream: (WebClient httpGet: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...') content asByteArray readStream.
On 3/21/19, H. Hirzel hannes.hirzel@gmail.com wrote:
Thanks for answering, Marcel
On 3/21/19, Marcel Taeumel marcel.taeumel@hpi.de wrote:
What about ...
Form fromBinaryStream: (WebClient httpGet: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...') contentStream.
Unfortunately a debugger window comes up [1]
... I think we should add a #fromUrl: besides Form class >> #fromFileNamed: and there distinguish between file paths and HTTP urls etc:
Form fromUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...'.
Yes, that would be fine to create a new convenience method
Form fromUrl:
after we have figured out the solution.
-- Hannes
[1] SecureSocketStream(Object)>>doesNotUnderstand: #reset Receiver: SecureSocketStream[inbuf:4kb/outbuf:4kb] Arguments and temporary variables: aMessage: reset exception: MessageNotUnderstood: SecureSocketStream>>reset resumeValue: nil Receiver's instance variables: recentlyRead: 0 socket: a Socket[destroyed] inBuffer: #[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0...etc... outBuffer: #[71 69 84 32 47 119 105 107 105 112 101 100 105 97 47 99 111 109 10...etc... inNextToWrite: 1 outNextToWrite: 1 lastRead: 0 timeout: 45 autoFlush: true bufferSize: 4096 binary: true shouldSignal: true ssl: nil sendBuf: #[23 3 3 0 232 61 247 6 24 144 238 146 249 51 100 82 127 29 104 195 17...etc... readBuf: #[203 4 102 97 151 46 237 173 196 165 168 136 21 56 21 225 6 113 183 1...etc... decoded: a ReadStream certIssues: 0
[] in ImageReadWriter class>>formFromStream: Receiver: ImageReadWriter Arguments and temporary variables: <<error during printing> Receiver's instance variables: superclass: Object methodDict: a MethodDictionary(#atEnd->(ImageReadWriter>>#atEnd "a CompiledMethod...etc... format: 65537 instanceVariables: #('stream') organization: ('accessing' nextImage nextPutImage:) ('stream access' atEnd close...etc... subclasses: {PCXReadWriter . XBMReadWriter . JPEGReadWriter . JPEGReadWriter2 ....etc... name: #ImageReadWriter classPool: a Dictionary(#ImageNotStoredSignal->nil #MagicNumberErrorSignal->nil...etc... sharedPools: nil environment: nil category: #'Graphics-Files'
Huh? WebResponse >> #contentStream has been there since 2012.
Best, Marcel Am 21.03.2019 20:37:40 schrieb H. Hirzel hannes.hirzel@gmail.com: It works if I replace
#contentStream
with
content asByteArray readStream
Form fromBinaryStream: (WebClient httpGet: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...') content asByteArray readStream.
On 3/21/19, H. Hirzel wrote:
Thanks for answering, Marcel
On 3/21/19, Marcel Taeumel wrote:
What about ...
Form fromBinaryStream: (WebClient httpGet: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...') contentStream.
Unfortunately a debugger window comes up [1]
... I think we should add a #fromUrl: besides Form class >> #fromFileNamed: and there distinguish between file paths and HTTP urls etc:
Form fromUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...'.
Yes, that would be fine to create a new convenience method
Form fromUrl:
after we have figured out the solution.
-- Hannes
[1] SecureSocketStream(Object)>>doesNotUnderstand: #reset Receiver: SecureSocketStream[inbuf:4kb/outbuf:4kb] Arguments and temporary variables: aMessage: reset exception: MessageNotUnderstood: SecureSocketStream>>reset resumeValue: nil Receiver's instance variables: recentlyRead: 0 socket: a Socket[destroyed] inBuffer: #[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0...etc... outBuffer: #[71 69 84 32 47 119 105 107 105 112 101 100 105 97 47 99 111 109 10...etc... inNextToWrite: 1 outNextToWrite: 1 lastRead: 0 timeout: 45 autoFlush: true bufferSize: 4096 binary: true shouldSignal: true ssl: nil sendBuf: #[23 3 3 0 232 61 247 6 24 144 238 146 249 51 100 82 127 29 104 195 17...etc... readBuf: #[203 4 102 97 151 46 237 173 196 165 168 136 21 56 21 225 6 113 183 1...etc... decoded: a ReadStream certIssues: 0
[] in ImageReadWriter class>>formFromStream: Receiver: ImageReadWriter Arguments and temporary variables:
Receiver's instance variables: superclass: Object methodDict: a MethodDictionary(#atEnd->(ImageReadWriter>>#atEnd "a CompiledMethod...etc... format: 65537 instanceVariables: #('stream') organization: ('accessing' nextImage nextPutImage:) ('stream access' atEnd close...etc... subclasses: {PCXReadWriter . XBMReadWriter . JPEGReadWriter . JPEGReadWriter2 ....etc... name: #ImageReadWriter classPool: a Dictionary(#ImageNotStoredSignal->nil #MagicNumberErrorSignal->nil...etc... sharedPools: nil environment: nil category: #'Graphics-Files'
Yes, WebResponse >> #contentStream is there but if I use it I get an error message, see my earlier mail in this thread where I include the details.
It seems that the stream is asked for #reset and that does not go well with the stream WebResponse uses.
SecureSocketStream(Object)>>doesNotUnderstand: #reset
So getting the whole content first and then to ask for a new stream is a workaround. It is a solution but maybe not the solution.
More investigation needed....
HH
On 3/22/19, Marcel Taeumel marcel.taeumel@hpi.de wrote:
Huh? WebResponse >> #contentStream has been there since 2012.
Best, Marcel Am 21.03.2019 20:37:40 schrieb H. Hirzel hannes.hirzel@gmail.com: It works if I replace
#contentStream
with
content asByteArray readStream
Form fromBinaryStream: (WebClient httpGet: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...') content asByteArray readStream.
On 3/21/19, H. Hirzel wrote:
Thanks for answering, Marcel
On 3/21/19, Marcel Taeumel wrote:
What about ...
Form fromBinaryStream: (WebClient httpGet: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...') contentStream.
Unfortunately a debugger window comes up [1]
... I think we should add a #fromUrl: besides Form class >> #fromFileNamed: and there distinguish between file paths and HTTP urls etc:
Form fromUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...'.
Yes, that would be fine to create a new convenience method
Form fromUrl:
after we have figured out the solution.
-- Hannes
[1] SecureSocketStream(Object)>>doesNotUnderstand: #reset Receiver: SecureSocketStream[inbuf:4kb/outbuf:4kb] Arguments and temporary variables: aMessage: reset exception: MessageNotUnderstood: SecureSocketStream>>reset resumeValue: nil Receiver's instance variables: recentlyRead: 0 socket: a Socket[destroyed] inBuffer: #[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0...etc... outBuffer: #[71 69 84 32 47 119 105 107 105 112 101 100 105 97 47 99 111 109 10...etc... inNextToWrite: 1 outNextToWrite: 1 lastRead: 0 timeout: 45 autoFlush: true bufferSize: 4096 binary: true shouldSignal: true ssl: nil sendBuf: #[23 3 3 0 232 61 247 6 24 144 238 146 249 51 100 82 127 29 104 195 17...etc... readBuf: #[203 4 102 97 151 46 237 173 196 165 168 136 21 56 21 225 6 113 183 1...etc... decoded: a ReadStream certIssues: 0
[] in ImageReadWriter class>>formFromStream: Receiver: ImageReadWriter Arguments and temporary variables:
Receiver's instance variables: superclass: Object methodDict: a MethodDictionary(#atEnd->(ImageReadWriter>>#atEnd "a CompiledMethod...etc... format: 65537 instanceVariables: #('stream') organization: ('accessing' nextImage nextPutImage:) ('stream access' atEnd close...etc... subclasses: {PCXReadWriter . XBMReadWriter . JPEGReadWriter . JPEGReadWriter2 ....etc... name: #ImageReadWriter classPool: a Dictionary(#ImageNotStoredSignal->nil #MagicNumberErrorSignal->nil...etc... sharedPools: nil environment: nil category: #'Graphics-Files'
On 22.03.2019, at 09:35, H. Hirzel hannes.hirzel@gmail.com wrote:
Yes, WebResponse >> #contentStream is there but if I use it I get an error message, see my earlier mail in this thread where I include the details.
It seems that the stream is asked for #reset and that does not go well with the stream WebResponse uses.
SecureSocketStream(Object)>>doesNotUnderstand: #reset
So getting the whole content first and then to ask for a new stream is a workaround. It is a solution but maybe not the solution.
More investigation needed....
No. The WebResponse stream is a non-resettable stream, it comes effectively from the network, so you can't meaningfully #reset it :) I can think of several ways to counter that, but not today :D
Best regards -Tobias
HH
On 3/22/19, Marcel Taeumel marcel.taeumel@hpi.de wrote:
Huh? WebResponse >> #contentStream has been there since 2012.
Best, Marcel Am 21.03.2019 20:37:40 schrieb H. Hirzel hannes.hirzel@gmail.com: It works if I replace
#contentStream
with
content asByteArray readStream
Form fromBinaryStream: (WebClient httpGet: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...') content asByteArray readStream.
On 3/21/19, H. Hirzel wrote:
Thanks for answering, Marcel
On 3/21/19, Marcel Taeumel wrote:
What about ...
Form fromBinaryStream: (WebClient httpGet: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...') contentStream.
Unfortunately a debugger window comes up [1]
... I think we should add a #fromUrl: besides Form class >> #fromFileNamed: and there distinguish between file paths and HTTP urls etc:
Form fromUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...'.
Yes, that would be fine to create a new convenience method
Form fromUrl:
after we have figured out the solution.
-- Hannes
[1] SecureSocketStream(Object)>>doesNotUnderstand: #reset Receiver: SecureSocketStream[inbuf:4kb/outbuf:4kb] Arguments and temporary variables: aMessage: reset exception: MessageNotUnderstood: SecureSocketStream>>reset resumeValue: nil Receiver's instance variables: recentlyRead: 0 socket: a Socket[destroyed] inBuffer: #[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0...etc... outBuffer: #[71 69 84 32 47 119 105 107 105 112 101 100 105 97 47 99 111 109 10...etc... inNextToWrite: 1 outNextToWrite: 1 lastRead: 0 timeout: 45 autoFlush: true bufferSize: 4096 binary: true shouldSignal: true ssl: nil sendBuf: #[23 3 3 0 232 61 247 6 24 144 238 146 249 51 100 82 127 29 104 195 17...etc... readBuf: #[203 4 102 97 151 46 237 173 196 165 168 136 21 56 21 225 6 113 183 1...etc... decoded: a ReadStream certIssues: 0
[] in ImageReadWriter class>>formFromStream: Receiver: ImageReadWriter Arguments and temporary variables:
Receiver's instance variables: superclass: Object methodDict: a MethodDictionary(#atEnd->(ImageReadWriter>>#atEnd "a CompiledMethod...etc... format: 65537 instanceVariables: #('stream') organization: ('accessing' nextImage nextPutImage:) ('stream access' atEnd close...etc... subclasses: {PCXReadWriter . XBMReadWriter . JPEGReadWriter . JPEGReadWriter2 ....etc... name: #ImageReadWriter classPool: a Dictionary(#ImageNotStoredSignal->nil #MagicNumberErrorSignal->nil...etc... sharedPools: nil environment: nil category: #'Graphics-Files'
Hello Tobias
On 3/22/19, Tobias Pape Das.Linux@gmx.de wrote:
On 22.03.2019, at 09:35, H. Hirzel hannes.hirzel@gmail.com wrote:
Yes, WebResponse >> #contentStream is there but if I use it I get an error message, see my earlier mail in this thread where I include the details.
It seems that the stream is asked for #reset and that does not go well with the stream WebResponse uses.
SecureSocketStream(Object)>>doesNotUnderstand: #reset
So getting the whole content first and then to ask for a new stream is a workaround. It is a solution but maybe not the solution.
More investigation needed....
No. The WebResponse stream is a non-resettable stream, it comes effectively from the network, so you can't meaningfully #reset it :)
Sure, I am aware that WebResponse is a non-resettable stream.
To reset the SecureSocketStream stream would mean that I have to get the content again from the web. This is not be what is wanted most of the time.
So somewhere we need to - get the content of the WebResponse object - convert it to an in-memory stream.
content asByteArray readStream.
theUrl := 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...'.
Form fromBinaryStream: (WebClient httpGet: theUrl) content asByteArray readStream.
I can think of several ways to counter that, but not today :D
Yes, I am interested in this, even in 3 .. 300 days time :-)
in the meantime I use the following patch in my application (method name and class suggested by Marcel) -- a useful solution..
NEW method Form class>>fromUrl: anUrlString
similar to
Form fromFileNamed: fileName
Yours and Marcel's feedback was helpful for me to get at this point.
...................................................................................................................................
'From Squeak5.2 of 13 December 2018 [latest update: #18221] on 22 March 2019 at 11:37:44 am'!
!Form class methodsFor: '*Add-Ons-BaseImage52patches' stamp: 'hjh 3/22/2019 11:37'! fromUrl: anUrlString "It is advisable to call this in a separate process"
self fromBinaryStream: (WebClient httpGet: anUrlString) content asByteArray readStream. ! !
...................................................................................................................................
An issue I had is that depending on the URL this may lock up the image, so it is advisable to put the call to #fromUrl: into another process.
Regards
Hannes
On Fri, 22 Mar 2019, H. Hirzel wrote:
Hello Tobias
On 3/22/19, Tobias Pape Das.Linux@gmx.de wrote:
On 22.03.2019, at 09:35, H. Hirzel hannes.hirzel@gmail.com wrote:
Yes, WebResponse >> #contentStream is there but if I use it I get an error message, see my earlier mail in this thread where I include the details.
It seems that the stream is asked for #reset and that does not go well with the stream WebResponse uses.
SecureSocketStream(Object)>>doesNotUnderstand: #reset
So getting the whole content first and then to ask for a new stream is a workaround. It is a solution but maybe not the solution.
More investigation needed....
No. The WebResponse stream is a non-resettable stream, it comes effectively from the network, so you can't meaningfully #reset it :)
Sure, I am aware that WebResponse is a non-resettable stream.
To reset the SecureSocketStream stream would mean that I have to get the content again from the web. This is not be what is wanted most of the time.
Or you could just pick the right converter based on the mime type of the response. #reset is sent by ImageReadWriter, because it uses trial and error to find the right converter for the image.
Levente
So somewhere we need to
get the content of the WebResponse object
convert it to an in-memory stream.
content asByteArray readStream.
theUrl := 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...'.
Form fromBinaryStream: (WebClient httpGet: theUrl) content asByteArray readStream.
I can think of several ways to counter that, but not today :D
Yes, I am interested in this, even in 3 .. 300 days time :-)
in the meantime I use the following patch in my application (method name and class suggested by Marcel) -- a useful solution..
NEW method Form class>>fromUrl: anUrlString
similar to
Form fromFileNamed: fileName
Yours and Marcel's feedback was helpful for me to get at this point.
...................................................................................................................................
'From Squeak5.2 of 13 December 2018 [latest update: #18221] on 22 March 2019 at 11:37:44 am'!
!Form class methodsFor: '*Add-Ons-BaseImage52patches' stamp: 'hjh 3/22/2019 11:37'! fromUrl: anUrlString "It is advisable to call this in a separate process"
self fromBinaryStream: (WebClient httpGet: anUrlString) content asByteArray readStream. ! !
...................................................................................................................................
An issue I had is that depending on the URL this may lock up the image, so it is advisable to put the call to #fromUrl: into another process.
Regards
Hannes
Hi Hannes,
I have implemented this in various ways in my InternetArchive client library—a work in (slow) progress over the last 3+ years. Note I did not realize a similar library had been written for Sophie ten years ago. This one was based on the Python client library which uses the current InternetArchive API.
I finally made it public in its current state here:
https://github.com/tcj/craggyaloofness https://github.com/tcj/craggyaloofness
Some examples for how to use it live in the IAExample* classes.
The following will display the famous Byte cover and restore the display after a click:
(IAItem named: 'byte-magazine-1981-08' ) displayItemTileJpeg
Anyway, you can find my code in the 'displaying graphics' instance method category of IADownload. Also note that you may be interested in seeing Form class>>#openImageInWindow:
Here is how I implemented some JPEG download & display in Squeak 5.2. These methods are taken from the IADownload and perhaps IAItem classes.
getResponse "returns a WebResponse object" ^ response := WebClient httpGet: self url.
downloadJpegIntoForm | s contents jww imageExtent form | s := ByteArray new writeStream. s binary. self getResponse. response streamTo: s size: response contentLength progress: nil. response close. contents := s contents. (JPEGReadWriter2 understandsImageFormat: (contents readStream)) ifFalse: [^ self error: 'cannot read jpeg']. jww := JPEGReadWriter2 new. imageExtent := jww imageExtent: contents. form := Form extent: imageExtent depth: 32. jww uncompress: contents into: form doDithering: false. ^ form
displayJpeg | form | form := self downloadJpegIntoForm. Display restoreAfter: [ form displayOn: Display ].
displayJpegInMorph | form morph | form := self downloadJpegIntoForm. morph := BorderedMorph newBounds: (form bounds). Display restoreAfter: [ form displayOn: Display ].
displayJpegInWindow | form morph window | self flag: #seeFormClassSideForUtilityMethod. form := self downloadJpegIntoForm. morph := form asMorph.
window := SystemWindow labelled: 'image'. window " addMorphCentered: (form asMorph);" addMorph: (form asMorph) frame: (0.0@0.0 corner: 1.0@1.0) . " addMorph: (form asMorph) fullFrame: (SystemWindow menuBoxFrame) ." window openInWorldExtent: (form extent scaleBy: 1.2 @ 1.2).
Let me know if I can help further. I believe there is also code in there for displaying downloaded GIFs and animated GIFs but I could be wrong.
Best, Tim
On Mar 21, 2019, at 3:51 AM, H. Hirzel <hannes.hirzel@gmail.com mailto:hannes.hirzel@gmail.com> wrote:
Hello
What is a good modern way in Squeak to load a picture from the web?
I am looking for an equivalent of
| pngPicURL aStream |
pngPicURL := 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...' https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617px-Squeak-x11.png'.
aStream := HTTPSocket httpGet: pngPicURL.
(ImageReadWriter formFromStream: aStream) asMorph openInHand
And answer or just comments are welcome.
Thank you.
Kind regards
Hannes
Self-reply:
I just noticed the #displayJpegInMorph method below is garbage and can be ignored.
Also, I believe there is a higher-level abstraction above JPEGReadWriter2. If I recall correctly, this higher level abstraction is connected to the Services architecture and can display many different formats of image files from disk. I didn't dig into it much and could be mistaken, but with further research it could prove useful.
Thanks again, Tim J
On Apr 2, 2019, at 8:15 AM, Tim Johnson digit@sonic.net wrote:
Hi Hannes,
I have implemented this in various ways in my InternetArchive client library—a work in (slow) progress over the last 3+ years. Note I did not realize a similar library had been written for Sophie ten years ago. This one was based on the Python client library which uses the current InternetArchive API.
I finally made it public in its current state here:
https://github.com/tcj/craggyaloofness https://github.com/tcj/craggyaloofness
Some examples for how to use it live in the IAExample* classes.
The following will display the famous Byte cover and restore the display after a click:
(IAItem named: 'byte-magazine-1981-08' ) displayItemTileJpeg
Anyway, you can find my code in the 'displaying graphics' instance method category of IADownload. Also note that you may be interested in seeing Form class>>#openImageInWindow:
Here is how I implemented some JPEG download & display in Squeak 5.2. These methods are taken from the IADownload and perhaps IAItem classes.
getResponse "returns a WebResponse object" ^ response := WebClient httpGet: self url.
downloadJpegIntoForm | s contents jww imageExtent form | s := ByteArray new writeStream. s binary. self getResponse. response streamTo: s size: response contentLength progress: nil. response close. contents := s contents. (JPEGReadWriter2 understandsImageFormat: (contents readStream)) ifFalse: [^ self error: 'cannot read jpeg']. jww := JPEGReadWriter2 new. imageExtent := jww imageExtent: contents. form := Form extent: imageExtent depth: 32. jww uncompress: contents into: form doDithering: false. ^ form
displayJpeg | form | form := self downloadJpegIntoForm. Display restoreAfter: [ form displayOn: Display ].
displayJpegInMorph | form morph | form := self downloadJpegIntoForm. morph := BorderedMorph newBounds: (form bounds). Display restoreAfter: [ form displayOn: Display ].
displayJpegInWindow | form morph window | self flag: #seeFormClassSideForUtilityMethod. form := self downloadJpegIntoForm. morph := form asMorph.
window := SystemWindow labelled: 'image'. window " addMorphCentered: (form asMorph);" addMorph: (form asMorph) frame: (0.0@0.0 corner: 1.0@1.0) . " addMorph: (form asMorph) fullFrame: (SystemWindow menuBoxFrame) ." window openInWorldExtent: (form extent scaleBy: 1.2 @ 1.2).
Let me know if I can help further. I believe there is also code in there for displaying downloaded GIFs and animated GIFs but I could be wrong.
Best, Tim
On Mar 21, 2019, at 3:51 AM, H. Hirzel <hannes.hirzel@gmail.com mailto:hannes.hirzel@gmail.com> wrote:
Hello
What is a good modern way in Squeak to load a picture from the web?
I am looking for an equivalent of
| pngPicURL aStream |
pngPicURL := 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617...' https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Squeak-x11.png/617px-Squeak-x11.png'.
aStream := HTTPSocket httpGet: pngPicURL.
(ImageReadWriter formFromStream: aStream) asMorph openInHand
And answer or just comments are welcome.
Thank you.
Kind regards
Hannes
squeak-dev@lists.squeakfoundation.org