Data URI
The data_uri plugin enables you to upload files as data URIs. This plugin is useful for example when using HTML5 Canvas.
plugin :data_uriUsage
The plugin will add the #<name>_data_uri writer to your model, which parses the given data URI string and uploads it to temporary storage:
photo.image_data_uri = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA" photo.image.mime_type #=> "image/png" photo.image.size #=> 43423If you're using Shrine::Attacher directly, you can use Attacher#assign_data_uri:
attacher.assign_data_uri("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA") attacher.file.mime_type #=> "image/png" attacher.file.size #=> 43423Errors
If the data URI wasn't correctly parsed, an error message will be added to the attachment column. You can change the default error message:
plugin :data_uri, error_message: "data URI was invalid" plugin :data_uri, error_message: ->(uri) { I18n.t("errors.data_uri_invalid") }Uploader options
Any options passed to Attacher#assign_data_uri will be forwarded to Attacher#assign (and Shrine#upload):
attacher.assign_data_uri(uri, metadata: { "filename" => "nature.jpg" })File extension
A data URI doesn't convey any information about the file extension, so when attaching from a data URI, the uploaded file location will be missing an extension. If you want the upload location to always have an extension, you can load the infer_extension plugin to infer it from the MIME type.
plugin :infer_extensionParsing data URI
If you just want to parse the data URI and create an IO object from it, you can do that with Shrine.data_uri. If the data URI cannot be parsed, a Shrine::Plugins::DataUri::ParseError will be raised.
# or YourUploader.data_uri(...) io = Shrine.data_uri("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA") io.content_type #=> "image/png" io.size #=> 21 io.read # decoded contentWhen the content type is ommited, text/plain is assumed. The parser also supports raw data URIs which aren't base64-encoded.
# or YourUploader.data_uri("...") io = Shrine.data_uri("data:,raw%20content") io.content_type #=> "text/plain" io.size #=> 11 io.read #=> "raw content"You can also assign a filename:
io = Shrine.data_uri("data:,content", filename: "foo.txt") io.original_filename #=> "foo.txt"Generating data URI
This plugin also adds UploadedFile#data_uri method, which returns a base64-encoded data URI of the file content, and UploadedFile#base64, which simply returns the file content base64-encoded.
uploaded_file.data_uri #=> "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA" uploaded_file.base64 #=> "iVBORw0KGgoAAAANSUhEUgAAAAUA"Instrumentation
If the instrumentation plugin has been loaded, the data_uri plugin adds instrumentation around data URI parsing.
# instrumentation plugin needs to be loaded *before* data_uri plugin :instrumentation plugin :data_uriParsing data URIs will trigger a data_uri.shrine event with the following payload:
| Key | Description |
|---|---|
:data_uri | The data URI string |
:uploader | The uploader class that sent the event |
A default log subscriber is added as well which logs these events:
Data URI (5ms) – {:uploader=>Shrine}
You can also use your own log subscriber:
plugin :data_uri, log_subscriber: -> (event) { Shrine.logger.info JSON.generate(name: event.name, duration: event.duration, uploader: event[:uploader]) }{"name":"data_uri","duration":5,"uploader":"Shrine"}
Or disable logging altogether:
plugin :data_uri, log_subscriber: nil