public static async Task <Image> LoadPhoto(Generator generator, string id, PhotoType type, string photoLayoutName) { // Load the photo from storage. If it doesn't exist then load the placeholder // image. Unlike pictures, photos are not cacheable because it's unlikely // that we'd want to reuse many photos, and even if we did it's unlikely that // the report designer would know which ones were likely to be reused. byte[] bits = null; try { bits = await generator.PhotoService.GetPhotoAsync(id, PhotoType.Full); } catch (Exception ex) { generator.RecordMissingPhoto(id); ex.Data.Add("PhotoTableLayout", photoLayoutName); ex.Data.Add("Photo", id); generator.Logger.LogException(ex); } // If the photo wasn't found then load the placeholder from the assembly if (bits == null) { Stream missing = Assembly.GetExecutingAssembly().GetManifestResourceStream("Demon.Report.photo-missing.jpg"); bits = new byte[missing.Length]; await missing.ReadAsync(bits, 0, bits.Length); // We could cache and reuse the placeholder, but it's a bit tricky to // do that here inside of the image loading routine. Probably best just // to pay the extra performance price than to complicate the procedure. // The main performance cost is the fetching of the data from storage, // but we don't do that here because we fetch from the assembly. And // the second performance cost is the increased size in the PDF, but // if the image isn't found then the PDF will have to be regenerated // anyway. } return(new Image(bits)); }