I'm trying to draw something in app with PencilKit. Now I want to export my drawings from my file, so I could open send it to other devices, and then open it(in format PKDrawing).
var canvasView = PKCanvasView()
//user does drawing...
let data = canvasView.drawing.dataRepresentation()
data will be of type Data. You can then write that to a file (https://developer.apple.com/documentation/foundation/nsdata/1414800-write) and export it however you want.
For example, you could use ExportFilesAction: https://www.youtube.com/watch?v=iDseNgvdTpA
To load this data back into a PKDrawing, you can:
let drawing = try? PKDrawing(data: dataToLoad)
Related
I'm working on the offline downloads section for a video streaming app. Currently, I'm able to download videos and also can see the file path for the downloads as follows:
Button(action: {
let fileManager = FileManager.default
do {
let resourceKeys : [URLResourceKey] = [.creationDateKey, .isDirectoryKey]
let documentsURL = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let enumerator = FileManager.default.enumerator(at: documentsURL,
includingPropertiesForKeys: resourceKeys,
options: [.skipsHiddenFiles], errorHandler: { (url, error) -> Bool in
print("directoryEnumerator error at \(url): ", error)
return true
})!
for case let fileURL as URL in enumerator {
let resourceValues = try fileURL.resourceValues(forKeys: Set(resourceKeys))
// print(fileURL.path, resourceValues.creationDate!, resourceValues.isDirectory!)
print(fileURL.path)
self.array.append(fileURL.path)
}
} catch {
print(error)
}
}){
Text("Check downloads")
}
//response when button is clicked
/private/var/mobile/Containers/Data/Application/AD90B554-3465-43DD-BAE2-04BC83F850A3/Documents/Bz75srG5nctDCnAWIspM.mp4
/private/var/mobile/Containers/Data/Application/AD90B554-3465-43DD-BAE2-04BC83F850A3/Documents/GWYgrgDVYaowxeGcOjzp.mp4
Since I've renamed the mp4 files using movie ID's (eg: GWYgrgDVYaowxeGcOjzp.mp4) my goal is to use this name to show which videos were downloaded and allow users to play the video. I'm able to do the name processing later on, but how am I able to get the downloaded mp4 files into a view like a VStack? I was thinking of looping through and adding the files into an array but wanted to check if there's a different way. Also, would be great if you could show me how to play a video using the path as the url. I've tried applying suggested methods but ended up with a "NSURLConnection finished with error - code -1002" error. Thank you!
I am downloading images from my server using this
let queue = DispatchQueue.global(qos: .userInteractive)
queue.async{ ...
And while images downloading user can tap the button. But sometimes this button doesn't work (when all images done button work correct).
How to solve this problem?
Donot access global queue for that, instead create a custom DispatchQueue with label, qos as .background and fetch the image, when done use DispatchQueue.main to return the image to the main queue
For e.g:
let queue = DispatchQueue(label: "myImageQueue", qos: .background)
queue.async {
...fetch image
DispatchQueue.main.async {
self.imageView.image = fetchedImage
}
}
Update 2:
I am still fighting to get the Icon save on the server.
Here what I am doing:
Item item = Sitecore.Context.Database.GetItem(imageId);
var imageIconUrl = Sitecore.Resources.Images.GetThemedImageSource(item.Appearance.Icon, ImageDimension.id32x32);
if (!string.IsNullOrEmpty(imageIconUrl))
{
// download the icon from the url
var iconFullPath = "e:\\pngIcons\\excelIcon.png";
var webClient = new System.Net.WebClient();
var downloadPath = "http://serverName/" + imageIconUrl;
webClient.DownloadFile(downloadPath, iconFullPath);
}
The variable downloadPath contains following string:
http://serverName/sitecore/shell/themes/standard/~/media/E503BA48C89B422D8400393F1C7086A7.ashx?h=32&thn=1&w=32&db=master
At the end what I can see is a png file but there is nothing in it. I also copy the string I get in variable downloadPath and pasted it in browser and I can see the Icon as follow:
Please let me know what I am doing wrong. Or How I can save the Icon. Thanks!!
Original Question:
The sitecore media item has a field "Media". I am talking about this:
I want to access this field. And the reason is:
If I access it with e.g. item.GetMediaStream() then I will get the complete file. I just want to save this little icon some how on the server. Is it possible ?
To get the icon/thumbnail you can use
var icon = Sitecore.Resources.Media.MediaManager.GetThumbnailUrl(mediaItem);
To get the url of the thumbnail.
If you want the stream of the thumbnail you need to use the MediaData object. Like this:
var mediaItem = new MediaItem(item)
var mediaData = new MediaData(mediaItem);
var iconStream = mediaData.GetThumbnailStream();
if (iconStream.Length < 0)
{
// The stream is empty, its probably a file that Sitecore can't
// generate a thumbnail for. Just use the Icon
var icon = item.Appearance.Icon;
}
This will get the icon or thumbnail of the actual media blob that is attached to the media item. If you just want the icon of the Sitecore item, then use Martins method.
If the stream is empty, then Sitecore can't generate a thumbnail for it, so you can just use the icon file for the media item template. item.Appearance.Icon
Appearance section (of Standard Template) has a field called Icon - this is where you can modify icon for the item. There is also a field called Thumbnail - your excel icon is sitting there
You can access the field programmatically, just mind that it starts with two underscores: __Icon:
var iconField = item.Fields["__Icon"];
var thumbnailField = item.Fields["__Thumbnail"];
Update: As you asked, below is the code that saves either of fields into the file on a drive. I have tested the code and confirm successfully stores icon from thumbnail field into the file:
string mediaItemPath = "/sitecore/media library/Files/ExcelFile";
string mediaFiedlName = "Thumbnail"; // also can be "__Icon"
var item = Sitecore.Context.Database.GetItem(mediaItemPath);
var iconField = item.Fields[mediaFiedlName];
if (iconField.HasBlobStream)
{
var thumb = (ImageField)iconField;
var bl = ((MediaItem)thumb.MediaItem).InnerItem.Fields["blob"];
Stream stream = bl.GetBlobStream();
byte[] buffer = new byte[8192];
using (FileStream fs = File.Create("D:\\you_file_name.ico")) // change your path
{
int length;
do
{
length = stream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, length);
}
while (length > 0);
fs.Flush();
fs.Close();
}
}
Update 2: If that does not help then I would advise to look around the way how that icon gets generated on Media field in Sitecore. In the worst case you may do the following - right click that icon and see its url. You will have something similar to what I assign to variable below:
string url = "http://test81/sitecore/shell/Applications/-/media/B4F61650CBE84EE396649602C0C48E1B.ashx?bc=White&db=master&h=128&la=en&mw=640&thn=1&vs=1&ts=b8046903-ae57-4f9d-9dd5-b626ee5eee90";
Of course your URL should have your hostname and media prefix and the rest of parameters. Then use Webclient with that modified URL:
WebClient webClient = new WebClient();
webClient.DownloadFile(url, "e:\\you_file_name.ico");
Not ideal, but may work. Note, that the code above should work in a context of already logged user, so you need to authorise you Webclient prior that (many articles on S.O. how to do that).
Please reply if that approach has worked for you (I've spent decent time writing and testing that code in debugger, so would want to know whether that helped)
I want to store the configuration of multiple GoogleCharts in a database and use them to create a dashboard of charts.
I currently store the options I supply for each chart in the database and have my dashboard working, displaying multiple charts.
I want to use the ChartEditor class to allow a user to amend a chart and then save the changes back to my database, so that the next time the dashboard is created, the changes are persisted.
Hence, when a user clicks on the OK button on the ChartEditor dialog, is there a way of accessing the changes to these options?
After crawling around, inspecting the ChartEditor object....
$.parseJSON(chartEditor.getChartSpecification())['options']
...returns what I'm looking for.
Just to add to Flippsie's answer, you can recreate the saved chart from the json returned from chartEditor.getChartSpecification()
var json = chartEditor.getChartSpecification(); // Or saved JSON value
var spec = JSON.parse(json);
// Get the chart details from the saved spec
var data = new google.visualization.DataTable(spec.dataTable);
var options = spec.options;
var chartType = spec.chartType || "BarChart";
// Instantiate and draw our chart, passing in some options.
window.chart = new google.visualization[chartType](document.getElementById('chart_div'));
chart.draw(data, options);
I have the following jsfiddle which he an existing image with a button that when clicked will change the image src randomly from an array.
JSFIDDLE: http://jsfiddle.net/GpSbd/7/
Some of these images will be very large, is it possible to reduce or compress the image file down before it does setImage and draws it onto the stage as i will eventually be uploading the images onto our server so want them to be as small as possible
// CHANGE IMAGE FUNCTION
$('#changeImage').on("click", function(){
var newImage = new Image();
var img = layer.get('#Image1')[0];
newImage.onload = function() {
<-- CAN I COMPRESS IT AT THIS STAGE? -->
img.setImage(newImage);
layer.draw();
};
var random = pictures[Math.floor(Math.random()*pictures.length)];
newImage.src = random;
});
You already have the image urls saved in your pictures[] array.
Just save that url (random) on your server and not the image itself.
This cuts your storage size by 20-100 times.
If the server needs to temporarily use the image, the server can use the url to fetch it.