Binarystream Text and Picture

I have always just saved my data out as a textstream and used PicturetostringMBS fn to add the picture data on the end of file. I have to use a Binary stream on this file but can’t get the picture out an in. How do I tack the graphic on the end of the bs?

OUT

  if ClipArt <> Nil then 'Usually write this
       Textoutputstream.Write "*JPG*"
       Textoutputstream.Write PictureToJPEGStringMBS(Clipart,100)
  end if

IN

  pictureString = tin.ReadAll
  pictureStartPos = InStr(pictureString,"*JPG*") + 5
  pictureString = Mid(pictureString,pictureStartPos)
  Clipart = JPEGStringToPictureMBS(pictureString ,true)

Shouldn’t both use “*JPG*”?

Sorry typo :frowning:

If I write pictures out with PictureToJPEGStringMBS, how do I read that back in with (JPEGStringToPictureMBS(pictureString ,true))? I don’t get how the binarystream knows where the picture data starts and stops? I tried writing JPG ahead of it so I could check the start and cal the length but no luck??

Var bs as Binarystream
bs.writeint16 myvalue
bs.WritePString “JPG
bs.WritePString PictureToJPEGStringMBS(Clipart,100)

Why do you have the 2 lines

bs.writeint16 myvalue
bs.WritePString “*JPG* ”

You don’t need them. The jpeg goes out as it is and then you read the file as is.

I Have other integers I want to write ahead of the picture.

Be aware of the limitation of WritePString: no more than 255 characters can be written that way (because the first written character is the count of the characters of your string, which, as a 8 bits chars, can only represent up to 256 as a number); that’s the nature of a PString.
Instead, you can do that:
bs.WriteInt32 MyString.Length
bs.Write MyString

That’s similar than PString, but you save yourself the length and avoid this limitation.

To read back:
MyString=bs.Read(bs.ReadInt32)

1 Like

Thanks Arnaud that did the trick :slight_smile:

You’re welcome :slightly_smiling_face:

@Martin_Fitzgibbons

JPEG (like many or all image formats) have “JFIF” at the beginning of the file. So using JPEG looks like useless to me (excepting for testings, maybe).

png have PNG
gif have GIF89a

etc.

wikipedia can help in those cases.

But, for macOS, maybe a bundle is a better idea to save your data in.

Am I reading you find the JPEG format useless because it has a “JFIF” header?
Interested in knowing why…

For Mac, could be (unless you want to hide it from the user, who can go into the package content and see all files).

If I was developing only for Mac, I’d love to use packages more often (as I think it’s a great idea); but with supporting Windows or Linux, sometimes it’s better to have a universal way to do things (e.g. save in a binary file) so you don’t have to manage things twice.
In the end, it’s a shame that it’s not convenient to use what each OS provides.

No. This f… forum stripped characters.

What I meant was to set a tag in the text as a separator from the JPEG part is useless. One have just to search for JFIF (magic number for JPEG) ad (s)he know where the image starts.

For the bundle suggestion, the OP used macOS Target Channel and do not talked of other platforms.

Of course, we are right (bundle for macOS only, other solutions for x-platforms).

In binary streams, it’s always good to separate all your data, regardless. In more complex code, you may not know if the source of the string has perhaps encoded the data or modified it, so it’s a good habit to get.

In this very specific case, yes, but:
1: with the BinaryStream’s ability to save the length of the string before saving the string itself, you also know the end location of the JPEG data (even if any footer would also appear in the middle of the data).
2: searching for “JFIF” takes time; saving a number of bytes takes place. I strongly think it’s better to spend, say, 32 bytes in a file, than loading the whole data string and searching for a substring.
3: as already stated, with searching for “JFIF”, you rely on the written data. If, for whatever reason, the data differs (e.g. you later decide to save&load as PNG, or you get the data from a component that changes its format), you have an additional step to do (and not forget): change “JFIF” to “PNG”. May not sound like a big deal per se, but can lead to errors, as you have to remember about it when you make changes.

Which doesn’t mean he’s not in this case. You made one extra assumption, I think.

But supporting bundles and other platforms is harder than in-house solutions (e.g. plain files with binary streams).

1 Like

Sorry, I was slightly wrong here. Please use MyString.Bytes instead of MyString.Length (for characters beyond the ASCII table).

1 Like