Use case: Get thumbnail upload URL for an annotation
Before you start
Before you upload a thumbnail for an annotation, ensure you have completed the following prerequisites:
- Project Access: Ensure you have the necessary permissions to modify annotations in the target project.
- Annotation Exists: The annotation must already exist before you can add a thumbnail to it.
- Image Preparation: Prepare your thumbnail image file (commonly PNG or JPEG format).
- Understand Upload Flow: The process requires three steps: get upload URL → upload to URL → finalize upload.
- Set Up SDK Environment: Confirm that your Unity environment is correctly configured with the Collaboration SDK.
How do I...?
Get a pre-signed URL to upload a thumbnail
To obtain a secure upload URL for an annotation thumbnail, follow these steps:
- Prepare the Project Identifier: Ensure you have the correct project identifier (GUID) for the project containing the annotation.
- Prepare the Annotation Identifier: Ensure you have the correct annotation identifier (GUID).
- Request Upload URL: Use the SDK to request a pre-signed upload URL.
- Upload Image: Use the returned URL to upload your thumbnail image directly to cloud storage.
- Finalize Upload: Call the finalize endpoint to complete the process (see finalize upload documentation).
Example:
var projectId = new ProjectId("87cf845f-8ca7-4b2f-9cc1-c3d731335810");
var annotationId = new AnnotationId("a1b2c3d4-e5f6-7890-abcd-ef1234567890");
var annotationReference = new annotationReference(projectId, annotationId);
// Step 1: Get the pre-signed upload URL
ReadThumbnailUploadUrlResult result = await annotationManagement.ReadThumbnailUploadUrlAsync(
annotationReference,
cancellationToken);
string uploadUrl = result.Url;
Debug.Log($"Thumbnail upload URL: {uploadUrl}");
// Step 2: Upload your image file to the URL (see complete workflow example below)
Complete thumbnail upload workflow
Here's a complete example showing the full process from getting the URL to finalizing:
public async Task UploadAnnotationThumbnail(
ProjectId projectId,
AnnotationId annotationId,
byte[] imageData,
string contentType = "image/png")
{
var annotationReference = new annotationReference(projectId, annotationId);
try
{
// Step 1: Get the pre-signed upload URL
ReadThumbnailUploadUrlResult urlResult = await annotationManagement.ReadThumbnailUploadUrlAsync(
annotationReference,
cancellationToken);
Debug.Log($"Obtained upload URL: {urlResult.Url}");
// Step 2: Upload the image data to the pre-signed URL
using (var httpClient = new HttpClient())
{
var content = new ByteArrayContent(imageData);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
HttpResponseMessage uploadResponse = await httpClient.PutAsync(urlResult.Url, content);
if (!uploadResponse.IsSuccessStatusCode)
{
Debug.LogError($"Upload failed: {uploadResponse.StatusCode}");
return;
}
Debug.Log("Thumbnail uploaded successfully");
}
// Step 3: Finalize the upload to make the thumbnail visible
await annotationManagement.FinalizeThumbnailUploadAsync(
annotationReference,
cancellationToken);
Debug.Log("Thumbnail finalized successfully");
}
catch (Exception ex)
{
Debug.LogError($"Failed to upload thumbnail: {ex.Message}");
}
}
Upload thumbnail from Unity Texture2D
To upload a thumbnail from a Unity Texture2D object:
public async Task UploadThumbnailFromTexture(
ProjectId projectId,
AnnotationId annotationId,
Texture2D thumbnail)
{
var annotationReference = new annotationReference(projectId, annotationId);
// Convert Texture2D to PNG byte array
byte[] imageData = thumbnail.EncodeToPNG();
if (imageData == null || imageData.Length == 0)
{
Debug.LogError("Failed to encode texture to PNG");
return;
}
// Get upload URL
ReadThumbnailUploadUrlResult urlResult = await annotationManagement.ReadThumbnailUploadUrlAsync(
annotationReference,
cancellationToken);
// Upload the PNG data
using (var httpClient = new HttpClient())
{
var content = new ByteArrayContent(imageData);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
await httpClient.PutAsync(urlResult.Url, content);
}
// Finalize the upload
await annotationManagement.FinalizeThumbnailUploadAsync(
annotationReference,
cancellationToken);
Debug.Log("Thumbnail from Texture2D uploaded successfully");
}
Handle upload with progress tracking
To track upload progress for large thumbnails:
public async Task UploadThumbnailWithProgress(
ProjectId projectId,
AnnotationId annotationId,
byte[] imageData,
IProgress<float> progress)
{
var annotationReference = new annotationReference(projectId, annotationId);
// Get upload URL
ReadThumbnailUploadUrlResult urlResult = await annotationManagement.ReadThumbnailUploadUrlAsync(
annotationReference,
cancellationToken);
progress?.Report(0.3f); // 30% - URL obtained
// Upload with progress tracking
using (var httpClient = new HttpClient())
{
var content = new ByteArrayContent(imageData);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
progress?.Report(0.5f); // 50% - Starting upload
HttpResponseMessage response = await httpClient.PutAsync(urlResult.Url, content);
response.EnsureSuccessStatusCode();
progress?.Report(0.8f); // 80% - Upload complete
}
// Finalize
await annotationManagement.FinalizeThumbnailUploadAsync(
annotationReference,
cancellationToken);
progress?.Report(1.0f); // 100% - Complete
}
Understanding pre-signed URLs
Pre-signed upload URLs provide secure, temporary access to cloud storage:
- Time-Limited: The URL expires after a certain period (typically minutes to hours)
- Direct Upload: Your application uploads directly to cloud storage, not through Unity servers
- Secure: The URL includes authentication tokens, so no additional credentials are needed
- PUT Request: Always use HTTP PUT method to upload to the pre-signed URL
- Content-Type: Set appropriate Content-Type header (e.g., "image/png", "image/jpeg")
Important notes
- Finalization Required: After uploading, you MUST call
FinalizeThumbnailUploadAsyncto make the thumbnail visible - URL Expiration: Use the upload URL promptly after obtaining it
- Single Use: Each URL is typically for one-time use; request a new URL for subsequent uploads
- Size Limits: Check with your Unity Cloud project settings for maximum thumbnail size limits
- Format Support: Commonly supported formats are PNG and JPEG; check documentation for full list
For related operations, see documentation on finalizing thumbnail upload and downloading thumbnails.
See the API documentation for more details on the ReadThumbnailUploadUrlAsync method.