JIMSMITH 0 Posted June 2 How do I place 3 to 4 images into a JSON object and send to a server. Also, need to be able to retrieve a string with 3 or 4 items from this server and store to file on a computer. If someone can point me to youtube videos or other google references on this it will be helpful. Code and examples compatible with Delphi XE11.3 (berlin or beyond). Thanks for your help. Share this post Link to post
Keesver 23 Posted June 2 You can encode the image using Base64 encoding. ChatGPT came up with this sample code. Calling TNetEncoding.Base64.EncodeBytesToString(Bytes) will do the actual conversion: uses System.JSON, System.SysUtils, System.Classes, System.NetEncoding; function ImageToBase64(const FilePath: string): string; var FileStream: TFileStream; Bytes: TBytes; begin FileStream := TFileStream.Create(FilePath, fmOpenRead); try SetLength(Bytes, FileStream.Size); FileStream.ReadBuffer(Pointer(Bytes)^, FileStream.Size); Result := TNetEncoding.Base64.EncodeBytesToString(Bytes); finally FileStream.Free; end; end; procedure SaveImageBase64ToJson; var JSONObject: TJSONObject; Base64String: string; JSONString: string; JSONFile: TStringList; begin Base64String := ImageToBase64('path/to/image.jpg'); JSONObject := TJSONObject.Create; try JSONObject.AddPair('name', 'Example Image'); JSONObject.AddPair('image_data', 'data:image/jpeg;base64,' + Base64String); JSONString := JSONObject.ToString; JSONFile := TStringList.Create; try JSONFile.Text := JSONString; JSONFile.SaveToFile('image_base64.json'); finally JSONFile.Free; end; finally JSONObject.Free; end; end; 1 Share this post Link to post
JIMSMITH 0 Posted September 13 I am finally trying to implement this code. The fact that the image type is captured with the data (data:image/jpeg;base64) causes problem when reading the data to save the image to a file. Anybody know how to make the reading of the value separate this information so that the proper file can be created and reread. The problem as I see it is that part of the file is text and the other part is encoded. So yes This does save the file, but now I need to read the file. Meanwhile I will see what I can find. data:image/jpeg;base64,' causes problems when reading the data. Share this post Link to post
Remy Lebeau 1392 Posted September 13 (edited) 4 hours ago, JIMSMITH said: The fact that the image type is captured with the data (data:image/jpeg;base64) causes problem when reading the data to save the image to a file. How so, exactly? 4 hours ago, JIMSMITH said: Anybody know how to make the reading of the value separate this information so that the proper file can be created and reread. It is just a string field, JSON doesn't care what its content is. When you get the string back, simply parse it to extract the base64 substring after the comma, and then decode that substring to get the raw bytes that you can then save to a file. IOW, just reverse the code that created the string. For example: procedure Base64ToImage(const Base64String, FilePath: string); var FileStream: TFileStream; Bytes: TBytes; begin Bytes := TNetEncoding.Base64.DecodeStringToBytes(Base64String); FileStream := TFileStream.Create(FilePath, fmCreate); try FileStream.WriteBuffer(Pointer(Bytes)^, Length(Bytes)); finally FileStream.Free; end; end; procedure LoadBase64JsonToImage; var JSONObject: TJSONObject; Base64String: string; JSONString: string; JSONFile: TStringList; begin JSONFile := TStringList.Create; try JSONFile.LoadFromFile('image_base64.json'); JSONString := JSONFile.Text; finally JSONFile.Free; end; JSONObject := TJSONObject.ParseJSONValue(JSONString) as TJSONObject; try JSONString := JSONObject.GetValue('image_data').Value; finally JSONObject.Free; end; Base64String := Copy(JSONString, Pos(',', JSONString)+1, MaxInt); Base64ToImage(Base64String, 'path/to/image.jpg'); end; Quote The problem as I see it is that part of the file is text and the other part is encoded. You are not supposed to save the entire string to a file. Just as the string wasn't produced entirely from a file to begin with, but from a text and a file. Edited September 13 by Remy Lebeau 1 Share this post Link to post
FaFaFooey 6 Posted September 13 Would BSON (Binary JSON) and not JSON be better in this situation? 1 Share this post Link to post
JIMSMITH 0 Posted September 14 2 hours ago, Remy Lebeau said: How so, exactly? It is just a string field, JSON doesn't care what its content is. When you get the string back, simply parse it to extract the base64 substring after the comma, and then decode that substring to get the raw bytes that you can then save to a file. IOW, just reverse the code that created the string. For example: procedure Base64ToImage(const Base64String, FilePath: string); var FileStream: TFileStream; Bytes: TBytes; begin Bytes := TNetEncoding.Base64.DecodeStringToBytes(Base64String); FileStream := TFileStream.Create(FilePath, fmCreate); try FileStream.WriteBuffer(Pointer(Bytes)^, Length(Bytes)); finally FileStream.Free; end; end; procedure LoadBase64JsonToImage; var JSONObject: TJSONObject; Base64String: string; JSONString: string; JSONFile: TStringList; begin JSONFile := TStringList.Create; try JSONFile.LoadFromFile('image_base64.json'); JSONString := JSONFile.Text; finally JSONFile.Free; end; JSONObject := TJSONObject.ParseJSONValue(JSONString) as TJSONObject; try JSONString := JSONObject.GetValue('image_data').Value; finally JSONObject.Free; end; Base64String := Copy(JSONString, Pos(',', JSONString)+1, MaxInt); Base64ToImage(Base64String, 'path/to/image.jpg'); end; You are not supposed to save the entire string to a file. Just as the string wasn't produced entirely from a file to begin with, but from a text and a file. Totally agree with your observation and I was attempting to explain this in my followup. Anyway you figured it out and solved this problem in the best way. possible. I sent a direct message and really thank you. Share this post Link to post