Okay, I believe I've finally worked it out. I've tested it pretty extensively now and I think I have it.
There's a bit involved, so I will take everyone through step by step.
Thanks to user MagnusGöransson who gave me the original inspiration for this idea from this forum post:
https://powerusers.microsoft.com/t5/Building-Power-Apps/Uploading-images-to-SharePoint-list-without-using-Flow/td-p/482731
Step 1) Split your datasources
The primary issue with Magnus's method was that attempting to store all that base64 data into a single data source meant that loading it in a gallery (in PowerApps) was impossible. The gallery just wouldn't load if you had 30+ items in your datasource with base64 strings in each item.
For this example I'll assume everything in your app comes from 1 primary datasource that contains everything. What you will need to do is split your datasource so that your Base64 string column is housed in it's own datasource, while everything else is in your primary datasource (text columns, choice columns etc).
Your secondary image datasource will look like this:
Your Title column should be a signle line of text column that contains a digit that mirrors your primary datasource ID column. Your Base64 columns are Multiline text columns.
Your Title column should be a single line of text column that contains a digit that mirrors your primary datasource ID column. Your Base64 columns are Multiline text columns.
Step 2) Hide your Base64 columns in Sharepoint
Once you have determined how many images you will need to store per form item in your app ( I need to store up to ten images per form item), and created that amount of columns in your secondary datasource, it will be necessary to hide those columns in your secondary datasource. If you don't hide them, the Sharepoint list won't load when you try to navigate to it in Sharepoint.
Step 3) Load both your datasources into PowerApps
If you haven't got one already, you'll need a custom card in your form, with an Add Image Control for each image.
*You'll also need a view only Datacard in your form that refers to the ID of the item in question*
Mine is called 'TextIDFormTextField'
It will look something like this:
Note the naming conventions of controls in the sidebar, and insert your own labels in the formula.
Step 4) Use this formula
Set(ImageBinaryRaw, JSON(Image001Thumbnail.Image , IncludeBinaryData));
Set(ImageBinary,Mid(ImageBinaryRaw, Find(",", ImageBinaryRaw)+1, Len(ImageBinaryRaw)-Find(",", ImageBinaryRaw)-1));
Patch(ImageListExample, LookUp(ImageListExample, Title = TextIDFormTextField.Text) ,{Image001: Concatenate("data:image/jpg;base64,", ImageBinary)});
You'll need to replace 'Image001Thumbnail' (Grey Thumbnail box in screenshot above) and 'ImageListExample' (Secondary Datasource). Please note: the forum doesn't like the 'data:image' string in the formula above, refer to screenshot ^^
Step 5) What the heck does this do, exactly?
Okay, so what this formula does is it looks up the secondary datasoucre and finds the item whose 'Title' column matches the ID of the primary data source list item. Then it patches the Base64 data into the appropriate Base64 column of the found item in the secondary data source.
Step 6) Viewable Thumbnails
The last step to ensure you've got this working right (and to give visual feedback to the end user that they've stored the image and can look at it again any time they open the item in question), is to have the thumbnail display the correct image.
Use this formula:
If(IsBlank(Image001AddButton.Media), LookUp(ImageListExample, Title = TextIDFormTextField.Text, Image001), Image001AddButton.Media)
Here we are once again looking up the secondary data source, cross-referencing the ID of the primary list item with the Title of the secondary list item, then pulling in the Base64 string into the thumb.
And Voila, it works:
Yes, I am a massive nerd.