Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions vnext/ReactUWP/Views/Image/ReactImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "ReactImage.h"

#include <winrt/Windows.Web.Http.h>
#include <winrt/Windows.Security.Cryptography.h>

#include "unicode.h"

Expand Down Expand Up @@ -75,6 +76,7 @@ namespace react {
winrt::Uri uri{ facebook::utf8ToUtf16(uriString) };
winrt::hstring scheme{ uri.SchemeName() };
bool needsDownload = (scheme == L"http") || (scheme == L"https");
bool inlineData = scheme == L"data";

try
{
Expand All @@ -84,16 +86,20 @@ namespace react {
if (needsDownload)
{
memoryStream = co_await GetImageStreamAsync(source);

if (!memoryStream)
{
m_onLoadEndEvent(*this, false);
}
}
else if (inlineData)
{
memoryStream = co_await GetImageInlineDataAsync(source);
}

if ((needsDownload || inlineData) && !memoryStream)
{
m_onLoadEndEvent(*this, false);
}

if (!needsDownload || memoryStream)
{
auto surface = needsDownload ?
auto surface = needsDownload || inlineData ?
winrt::LoadedImageSurface::StartLoadFromStream(memoryStream) :
winrt::LoadedImageSurface::StartLoadFromUri(uri);

Expand Down Expand Up @@ -166,5 +172,32 @@ namespace react {

return nullptr;
}

winrt::IAsyncOperation<winrt::InMemoryRandomAccessStream> GetImageInlineDataAsync(ImageSource source)
{
size_t start = source.uri.find(',');
if (start == std::string::npos || start + 1 > source.uri.length())
return nullptr;

try
{
co_await winrt::resume_background();

std::string_view base64String(source.uri.c_str() + start + 1, source.uri.length() - start - 1);
auto buffer = winrt::Windows::Security::Cryptography::CryptographicBuffer::DecodeFromBase64String(facebook::react::unicode::utf8ToUtf16(base64String));

winrt::InMemoryRandomAccessStream memoryStream;
co_await memoryStream.WriteAsync(buffer);
memoryStream.Seek(0);

return memoryStream;
}
catch (winrt::hresult_error const&)
{
// Base64 decode failed
}

return nullptr;
}
}
} // namespace react::uwp
1 change: 1 addition & 0 deletions vnext/ReactUWP/Views/Image/ReactImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@ namespace react {

// Helper functions
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::InMemoryRandomAccessStream> GetImageStreamAsync(ImageSource source);
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::InMemoryRandomAccessStream> GetImageInlineDataAsync(ImageSource source);
}
} // namespace react::uwp
9 changes: 9 additions & 0 deletions vnext/Universal.SampleApp/index.uwp.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,15 @@ export default class Bootstrap extends Component {
onError={() => { console.log('image onError!'); }}
/>
</View>
<View style={{ backgroundColor: 'yellow', marginTop: 15 }}>
<Image
style={{ width: 66, height: 58 }}
source={{ width: 66, height: 58,
uri:
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=="
}}
/>
</View>
<View style={{ flexDirection: 'row', alignItems: 'center', marginTop: 15 }}>
<CheckBox
onValueChange={value => this.setState({ checkBoxIsOn: value })}
Expand Down