public void TestImageJob() { var ms = new MemoryStream(); var j = new ImageJob(ImageBuilderTest.GetBitmap(100, 200), ms, new Instructions("width=50;format=jpg")); c.CurrentImageBuilder.Build(j); Assert.AreEqual(j.SourceWidth, 100); Assert.AreEqual(j.SourceHeight, 200); Assert.AreEqual(j.ResultFileExtension, "jpg"); Assert.AreEqual(j.ResultMimeType, "image/jpeg"); }
static void Run(Options options) { using (var stream = File.OpenRead(options.Input)) { var outputFileName = GetOutputFilename(options.Input); using (var outStream = File.OpenWrite(outputFileName)) { var hints = new ResampleHints { SharpenWhen = SharpenWhen.Downscaling, SharpenPercent = 100 }; using (var job = new ImageJob()) { job.Decode(stream, false) .ConstrainWithin(options.Width, options.height) .SaturationSrgb(0) .EncodeToStream(outStream, false, new MozJpegEncoder(90)) .Finish() .InProcessAsync() .Wait(); } } } }
protected void btnUploadAndGenerate_Click(object sender, EventArgs e) { Dictionary <string, string> versions = new Dictionary <string, string>(); //Define the version to generate versions.Add("_thumb", "width=100&height=100&crop=auto&format=jpg"); //Crop to square thumbnail versions.Add("_medium", "maxwidth=400&maxheight=400format=jpg"); //Fit inside 400x400 area, jpeg versions.Add("_large", "maxwidth=1900&maxheight=1900&format=jpg"); //Fit inside 1900x1200 area //Loop through each uploaded file foreach (string fileKey in HttpContext.Current.Request.Files.Keys) { HttpPostedFile file = HttpContext.Current.Request.Files[fileKey]; if (file.ContentLength <= 0) { continue; //Skip unused file controls. } //Generate each version foreach (string suffix in versions.Keys) { ImageJob i = new ImageJob(file, "~/uploads/<guid>" + suffix + ".<ext>", new ResizeSettings(versions[suffix])); i.CreateParentDirectory = true; //Auto-create the uploads directory. i.Build(); } } }
public void Resize(string source, string destination, int height) { try { GdiPlusInterop.CheckGdiPlus(); using (var sourceStream = _diskProvider.OpenReadStream(source)) { using (var outputStream = _diskProvider.OpenWriteStream(destination)) { var settings = new Instructions(); settings.Height = height; var job = new ImageJob(sourceStream, outputStream, settings); ImageBuilder.Current.Build(job); } } } catch { if (_diskProvider.FileExists(destination)) { _diskProvider.DeleteFile(destination); } throw; } }
private async Task <string> EncodeToPreferredFormatAndSave(byte[] formFileContent, string name) { using (var job = new ImageJob()) { var info = await ImageJob.GetImageInfo(new BytesSource(formFileContent)); GetEncoder(info, out IEncoderPreset encoder, out string expectedExt); var resized = await job.Decode(formFileContent) .EncodeToBytes(encoder) .Finish() .InProcessAndDisposeAsync(); var result = resized.First.TryGetBytes(); if (result.HasValue) { var fileName = Path.GetFileName(name); var ext = Path.GetExtension(fileName); var newFileName = name.Replace(ext, expectedExt); return(await _blog.SaveFile(result.Value.Array, newFileName)); } } return(null); }
public void Resize(string source, string destination, int height) { try { if (!_diskProvider.CanUseGDIPlus()) { throw new Exception("Can't resize without libgdiplus."); } using (var sourceStream = _diskProvider.OpenReadStream(source)) { using (var outputStream = _diskProvider.OpenWriteStream(destination)) { var settings = new Instructions(); settings.Height = height; var job = new ImageJob(sourceStream, outputStream, settings); ImageBuilder.Current.Build(job); } } } catch { if (_diskProvider.FileExists(destination)) { _diskProvider.DeleteFile(destination); } throw; } }
static void Run(Options options) { var directory = Path.GetDirectoryName(options.Input); var files = Directory.GetFiles(directory, "*.jpg"); foreach (var filePath in files) { using (var stream = File.OpenRead(filePath)) { var outputFileName = GetOutputFileName(filePath); using (var outStream = new FileStream(outputFileName, FileMode.Create, FileAccess.Write)) { using (var job = new ImageJob()) { job.Decode(stream, false) .ConstrainWithin(options.Width, options.Height) .ColorFilterSrgb(ColorFilterSrgb.Grayscale_Bt709) .EncodeToStream(outStream, false, new MozJpegEncoder(90)) .Finish() .InProcessAsync() .Wait(); } } } } }
public void AddImageJob(Bitmap bmp, int index, string language, string psmMode, string engineMode, bool run302, bool music302) { var job = new ImageJob { FileName = FileUtil.GetTempFileName(".png"), Index = index, Completed = DateTime.MaxValue, Bitmap = bmp, LanguageCode = language + (music302 ? "+music" : string.Empty), PsmMode = psmMode, EngineMode = engineMode, Run302 = run302 }; if (_abort) { return; } lock (QueueLock) { _jobQueue.Enqueue(job); } bmp.Save(job.FileName, System.Drawing.Imaging.ImageFormat.Png); ThreadPool.QueueUserWorkItem(DoOcr, job); }
public Stream ProcessingImage(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } if (stream.Position > 0) { stream.Seek(0, SeekOrigin.Begin); } Stream destination = new MemoryStream(); var imageJob = new ImageJob(); imageJob.Source = stream; imageJob.Dest = destination; imageJob.Settings = new ResizeSettings(this.BuilderConfig()); imageJob.DisposeSourceObject = false; imageJob.AddFileExtension = true; imageJob.ResetSourceStream = true; ImageBuilder.Current.Build(imageJob); return(destination); }
public static void GenerateVersions(string original) { Dictionary <string, string> versions = new Dictionary <string, string>(); //Define the versions to generate and their filename suffixes. versions.Add("_thumb", "width=300&height=300&crop=auto&format=jpg"); versions.Add("_large", "maxwidth=1024&maxheight=768&format=jpg&mode=max"); string basePath = PathUtils.RemoveExtension(original); //Generate each version foreach (string suffix in versions.Keys) { var job = new ImageJob { Source = original, Dest = basePath + suffix, Instructions = new Instructions(versions[suffix]), DisposeSourceObject = false, AddFileExtension = true, CreateParentDirectory = true }; ImageBuilder.Current.Build(job); //Let the image builder add the correct extension based on the output file type //ImageBuilder.Current.Build(original, basePath + suffix, // new ResizeSettings(versions[suffix]), false, true); } }
public static void GenerateVersions(Stream source, string baseFileName) { Dictionary <string, string> versions = new Dictionary <string, string>(); //Define the versions to generate and their filename suffixes. versions.Add("_thumb", "width=300&height=300&crop=auto&format=jpg"); versions.Add("_large", "maxwidth=1024&maxheight=768&format=jpg&mode=max"); // Ensure that no extensions are in the file name. string basePath = PathUtils.RemoveExtension(baseFileName); using (source) { //Generate each version foreach (string suffix in versions.Keys) { var job = new ImageJob { Source = source, Dest = basePath + suffix, Instructions = new Instructions(versions[suffix]), DisposeSourceObject = false, AddFileExtension = true, ResetSourceStream = true, CreateParentDirectory = true }; ImageBuilder.Current.Build(job); } } }
private async Task DuplicateSmallerImageIfLargeAndSave(byte[] formFileContent, string name, int ifLargerThan, int constrainX, int constrainY) { using (var job = new ImageJob()) { var info = await ImageJob.GetImageInfo(new BytesSource(formFileContent)); if (info.ImageWidth > ifLargerThan) { GetEncoder(info, out IEncoderPreset encoder, out string expectedExt); var resized = await job.Decode(formFileContent) .ConstrainWithin((uint)constrainX, (uint)constrainY) .EncodeToBytes(encoder) .Finish() .InProcessAndDisposeAsync(); var result = resized.First.TryGetBytes(); if (result.HasValue) { var fileName = Path.GetFileName(name); var ext = Path.GetExtension(fileName); var newFileName = name.Replace(ext, "-sm" + expectedExt); await _blog.SaveFile(result.Value.Array, newFileName); } } } }
public static ImageInfo Resize(Stream input, int?desiredWidth, int?desiredHeight) { input.Position = 0; MemoryStream outputStream = new MemoryStream(); Instructions instructions = new Instructions { Width = desiredWidth, Height = desiredHeight, Mode = FitMode.Max, Scale = ScaleMode.DownscaleOnly, OutputFormat = OutputFormat.Jpeg, JpegQuality = 90 }; ImageJob job = new ImageJob(input, outputStream, instructions) { ResetSourceStream = true, DisposeSourceObject = false, }; ImageBuilder.Current.Build(job); ImageInfo result = new ImageInfo { MimeType = job.ResultMimeType, Width = (int)job.ResultInfo["final.width"], Height = (int)job.ResultInfo["final.height"], Image = outputStream }; return(result); }
void btnUpload_Click(object sender, EventArgs e) { //Loop through each uploaded file foreach (string fileKey in HttpContext.Current.Request.Files.Keys) { HttpPostedFile file = HttpContext.Current.Request.Files[fileKey]; if (file.ContentLength <= 0) { continue; //Skip unused file controls. } //The resizing settings can specify any of 30 commands.. See http://imageresizing.net for details. //Destination paths can have variables like <guid> and <ext> ImageJob i = new ImageJob(file, "~/uploads/<guid>_<filename:A-Za-z0-9>.<ext>", new ResizeSettings("width=200&height=200&format=jpg&crop=auto")); i.CreateParentDirectory = true; //Auto-create the uploads directory. i.Build(); } //Here's an example of getting a byte array for sending to SQL ////Loop through each uploaded file //foreach (string fileKey in HttpContext.Current.Request.Files.Keys) { // HttpPostedFile file = HttpContext.Current.Request.Files[fileKey]; // //The resizing settings can specify any of 30 commands.. See http://imageresizing.net for details. // ResizeSettings resizeCropSettings = new ResizeSettings("width=200&height=200&format=jpg&crop=auto"); // using (MemoryStream ms = new MemoryStream()) { // //Resize the image // ImageBuilder.Current.Build(file, ms, resizeCropSettings); // //Upload the byte array to SQL: ms.ToArray(); // } //} }
public async Task TestConstraints() { var imageBytes = Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlPM0jRW/QAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII="); using (var b = new ImageJob()) { var r = await b.Decode(imageBytes). Constrain(new Constraint(ConstraintMode.Fit_Crop, 10, 20) { CanvasColor = null, H = 20, W = 10, Hints = new ResampleHints() { InterpolationColorspace = ScalingFloatspace.Linear, DownFilter = InterpolationFilter.Mitchell, ResampleWhen = ResampleWhen.Size_Differs_Or_Sharpening_Requested, SharpenWhen = SharpenWhen.Always, SharpenPercent = 15, UpFilter = InterpolationFilter.Ginseng }, Mode = ConstraintMode.Fit_Crop }) .EncodeToBytes(new GifEncoder()).Finish().InProcessAsync(); Assert.Equal(10, r.First.Width); Assert.Equal(20, r.First.Height); Assert.True(r.First.TryGetBytes().HasValue); } }
public Photo(HttpPostedFileBase file, NameValueCollection defaultQuery = null, NameValueCollection preprocessingQuery = null) { Id = Guid.NewGuid(); OriginalName = file.FileName; string newPath = PathUtils.SetExtension(Id.ToString(), PathUtils.GetExtension(OriginalName)); FilePath = newPath; if (!Directory.Exists(StoragePath)) { Directory.CreateDirectory(StoragePath); } if (preprocessingQuery == null || !Config.Current.Pipeline.IsAcceptedImageType(OriginalName)) { file.SaveAs(Path.Combine(StoragePath, newPath)); } else { var j = new ImageJob(file, Path.Combine(StoragePath, Id.ToString()), new ResizeSettings(preprocessingQuery)); j.AddFileExtension = true; j.Build(); FilePath = Path.GetFileName(j.FinalPath); } Query = defaultQuery != null ? defaultQuery : new NameValueCollection(); }
public void TestContentTypeDetection() { var pngBytes = Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlPM0jRW/QAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII="); Assert.Equal("image/png", ImageJob.GetContentTypeForBytes(pngBytes)); Assert.True(ImageJob.CanDecodeBytes(pngBytes)); var jpegBytes = new byte[] { 0xFF, 0xD8, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; Assert.Equal("image/jpeg", ImageJob.GetContentTypeForBytes(jpegBytes)); Assert.True(ImageJob.CanDecodeBytes(jpegBytes)); var gifBytes = new byte[] { (byte)'G', (byte)'I', (byte)'F', (byte)'8', (byte)'9', (byte)'a', 0, 0, 0, 0, 0, 0, 0 }; Assert.Equal("image/gif", ImageJob.GetContentTypeForBytes(gifBytes)); Assert.True(ImageJob.CanDecodeBytes(gifBytes)); var webpBytes = new byte[] { (byte)'R', (byte)'I', (byte)'F', (byte)'F', 0, 0, 0, 0, (byte)'W', (byte)'E', (byte)'B', (byte)'P' }; Assert.Equal("image/webp", ImageJob.GetContentTypeForBytes(webpBytes)); Assert.True(ImageJob.CanDecodeBytes(webpBytes)); var nonsenseBytes = new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', 0, 0, 0, 0, 0, 0, 0 }; Assert.Equal(null, ImageJob.GetContentTypeForBytes(nonsenseBytes)); Assert.False(ImageJob.CanDecodeBytes(nonsenseBytes)); }
public async Task TestCustomDownscalingAndDecodeEncodeResults() { var imageBytes = Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlPM0jRW/QAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII="); using (var b = new ImageJob()) { var cmd = new DecodeCommands { JpegDownscaleHint = new Size(20, 20), JpegDownscalingMode = DecoderDownscalingMode.Fastest, DiscardColorProfile = true }; var r = await b.Decode(new BytesSource(imageBytes), 0, cmd) .Distort(30, 20, new ResampleHints().SetSharpen(50.0f, SharpenWhen.Always).SetResampleFilters(InterpolationFilter.Robidoux_Fast, InterpolationFilter.Cubic)) .ConstrainWithin(5, 5) .EncodeToBytes(new LodePngEncoder()).Finish().InProcessAsync(); Assert.Equal(5, r.First.Width); Assert.True(r.First.TryGetBytes().HasValue); Assert.Equal(r.DecodeResults.First().Width, 1); Assert.Equal(r.DecodeResults.First().Height, 1); Assert.Equal(r.DecodeResults.First().PreferredExtension, "png"); Assert.Equal(r.DecodeResults.First().PreferredMimeType, "image/png"); Assert.Equal(r.EncodeResults.First().Width, 5); Assert.Equal(r.EncodeResults.First().Height, 3); Assert.Equal(r.EncodeResults.First().PreferredExtension, "png"); Assert.Equal(r.EncodeResults.First().PreferredMimeType, "image/png"); } }
protected void txtUpload_FileUploadComplete(object sender, DevExpress.Web.FileUploadCompleteEventArgs e) { string counter = DateTime.Now.Ticks.ToString(); string ext = Path.GetExtension(e.UploadedFile.FileName); string replaced_icode = txtICode.Text.ToLower().Replace("\\", "X1").Replace("/", "X2").Replace(":", "X3").Replace("*", "X4").Replace("?", "X5").Replace("\"", "X6").Replace("<", "X7").Replace(">", "X8").Replace("|", "X9"); replaced_icode = replaced_icode.Replace("`", "Y001").Replace("~", "Y002").Replace("!", "Y1").Replace("@", "Y2").Replace("#", "Y3").Replace("$", "Y4").Replace("%", "Y5").Replace("^", "Y6").Replace("&", "Y7"); replaced_icode = replaced_icode.Replace("(", "Y9").Replace(")", "Y0").Replace("-", "Z1").Replace("+", "Z2").Replace("_", "Z3").Replace("=", "Z4").Replace("[", "Z5").Replace("]", "Z6").Replace("{", "Z7").Replace("}", "Z8").Replace(";", "Z9").Replace(",", "C1").Replace(".", "C2") + counter; string filename = replaced_icode + ext; txtImageFilename.Text = filename; string strSavePath = "~\\ItemImages\\" + filename; ///hdImageName.Text = strSavePath; //e.UploadedFile.SaveAs(Server.MapPath(strSavePath)); string url = ResolveClientUrl(filename);// + "?" + strSavePath + "?" + DateTime.Now.Ticks.ToString(); e.CallbackData = url; foreach (string filekey in HttpContext.Current.Request.Files.Keys) { HttpPostedFile file = HttpContext.Current.Request.Files[filekey]; if (file.ContentLength <= 0) { continue; //Skip unused file controls. } ImageJob i = new ImageJob(file, "~\\itemImages\\" + filename, new ImageResizer.ResizeSettings("width=500;height=400;format=png;mode=max")); i.CreateParentDirectory = true; //Auto-create the uploads directory. i.Build(); // AddImage(filename, strSavePath); } }
//public MemoryStream Resize(string path, Qualitiers qualitier) //{ // FileStream input = System.IO.File.OpenRead(path); // MemoryStream resultStream = new MemoryStream(); // if (qualitier.Height==0 && qualitier.Widht==0) // { // input.CopyTo(resultStream); // } // else // { // ImageJob job = new ImageJob(input, resultStream, new Instructions // { // Width = qualitier.Widht, // Height = qualitier.Height, // JpegQuality = qualitier.Quality, // Mode = TypesComparision.GetInstance().Convert(qualitier.Fitmode) // }); // job.Build(); // } // resultStream.Seek(0, SeekOrigin.Begin); // return resultStream; //} public MemoryStream Resize(string path, Qualitiers qualitier) { FileStream input = System.IO.File.OpenRead(path); MemoryStream resultStream = new MemoryStream(); ImageJob job; if (qualitier.Height == 0 && qualitier.Widht == 0) { job = new ImageJob(input, resultStream, new Instructions { JpegQuality = qualitier.Quality, Mode = TypesComparision.GetInstance().Convert(qualitier.Fitmode) }); } else { job = new ImageJob(input, resultStream, new Instructions { Width = qualitier.Widht, Height = qualitier.Height, JpegQuality = qualitier.Quality, Mode = TypesComparision.GetInstance().Convert(qualitier.Fitmode) }); } job.Build(); resultStream.Seek(0, SeekOrigin.Begin); return(resultStream); }
public static string FileUploadResize(HttpPostedFileBase file, String parentFileName = null, bool ck = false) { if (file != null) { var allowedExtensions = new[] { ".png", ".gif", ".jpeg", ".jpg" }; var checkextension = Path.GetExtension(file.FileName).ToLower(); if (!allowedExtensions.Contains(checkextension)) { return(null); } var fileName = (!string.IsNullOrEmpty(parentFileName) ? parentFileName + "_" : "") + Guid.NewGuid().ToString().Split('-').First() + "_" + file.FileName; fileName = fileName.Replace(" ", ""); var pathName = System.Web.HttpContext.Current.Server.MapPath(Settings.ImageUploadFolderPath); if (ck) { pathName = pathName + "/ckimages"; } var path = Path.Combine(pathName, fileName); ImageJob i = new ImageJob(file, path, new ImageResizer.Instructions( "format=jpg;mode=max;scale=both")); // ----> ვინახავთ ფაილში i.CreateParentDirectory = true; //Auto-create the uploads directory. i.Build(); return(fileName); } return(null); }
private static async Task <Stream> GenerateImageAsync(byte[] originalImage, ImageFileSpec imageFileSpec, Table table) { var individualImageStopwatch = new Stopwatch(); individualImageStopwatch.Start(); using (var job = new ImageJob()) { var buildNode = job.Decode(originalImage); var resampleHints = new ResampleHints(); if (imageFileSpec.FileSpecFormat != FileSpecFormat.WebPLossless && imageFileSpec.SharpeningAmount > 0) { resampleHints.SetSharpen(imageFileSpec.SharpeningAmount, SharpenWhen.Downscaling).SetResampleFilters(imageFileSpec.InterpolationFilter, null); } buildNode = buildNode.ConstrainWithin(imageFileSpec.PixelLength, imageFileSpec.PixelLength, resampleHints); IEncoderPreset encoderPreset; if (imageFileSpec.FileSpecFormat == FileSpecFormat.WebPLossless) { encoderPreset = new WebPLosslessEncoder(); } else if (imageFileSpec.FileSpecFormat == FileSpecFormat.WebPLossy) { encoderPreset = new WebPLossyEncoder(imageFileSpec.Quality); } else { encoderPreset = new MozJpegEncoder(imageFileSpec.Quality, true); } var result = await buildNode .EncodeToBytes(encoderPreset) .Finish() .SetSecurityOptions(new SecurityOptions() .SetMaxDecodeSize(new FrameSizeLimit(99999, 99999, 200)) .SetMaxFrameSize(new FrameSizeLimit(99999, 99999, 200)) .SetMaxEncodeSize(new FrameSizeLimit(99999, 99999, 200))) .InProcessAsync(); var newImageBytes = result.First.TryGetBytes(); if (newImageBytes.HasValue) { var newStream = new MemoryStream(newImageBytes.Value.ToArray()); individualImageStopwatch.Stop(); var kb = newImageBytes.Value.Count / 1024; var size = $"{kb} kb"; table.AddRow(imageFileSpec.ToString(), individualImageStopwatch.ElapsedMilliseconds.ToString(), size); return(newStream); } } individualImageStopwatch.Stop(); AnsiConsole.Render(new Markup("[bold red]Something went wrong with an image generation.[/]")); return(null); }
/// <summary> /// Adds alternate pipeline based on WIC. Invoked by &builder=wic. /// This method doesn't handle job.DisposeSource or job.DesposeDest or settings filtering, that's handled by ImageBuilder. /// Handles all the work for turning 'source' into a byte[]/long pair. /// </summary> /// <param name="job"></param> /// <returns></returns> protected override RequestedAction BuildJob(ImageJob job) { if (!"wic".Equals(job.Settings["builder"])) { return(RequestedAction.None); } //Convert the source stream to a byte[] array and length. byte[] data = null; long lData = 0; //This step gets a Stream instance, copies it to a MemoryStream, then accesses the underlying buffer to get the byte[] and length we need. Stream s = null; bool disposeStream = !(job.Source is Stream); long originalPosition = 0; bool restoreStreamPosition = false; try { //Get a Stream instance for the job string path; s = c.CurrentImageBuilder.GetStreamFromSource(job.Source, job.Settings, ref disposeStream, out path, out restoreStreamPosition); if (s == null) { return(RequestedAction.None); //We don't support the source object! } if (job.ResetSourceStream) { restoreStreamPosition = true; } job.SourcePathData = path; //Save the original stream positione originalPosition = (restoreStreamPosition) ? s.Position : -1; data = StreamExtensions.CopyOrReturnBuffer(s, out lData, false, 0x1000); } finally { if (s != null && restoreStreamPosition && s.CanSeek) { s.Seek(originalPosition, SeekOrigin.Begin); } if (disposeStream) { s.Dispose(); } } //Ok, now we have our byte[] and length. //Let's find out if transparency is supported. IEncoder managedEncoder = c.Plugins.GetEncoder(job.Settings, job.SourcePathData); bool supportsTransparency = managedEncoder.SupportsTransparency; RequestedAction result = BuildJobWic(data, lData, job, supportsTransparency); GC.KeepAlive(data); return(result); }
private static Maybe<TimeSpan> TryGetTimeSpan(ImageJob imageJob) { using (var tesseractProcess = new TesseractProcess(imageJob.SliceImagePath)) { var tesseractOutput = tesseractProcess.Execute(); return OutputFileProcessor.TryGetTime(tesseractOutput); } }
static async Task Main(string[] args) { // From https://github.com/imazen/imageflow-dotnet#getting-image-dimensions-and-format var imageBytes = Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlPM0jRW/QAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII="); var info = await ImageJob.GetImageInfo(new BytesSource(imageBytes)); Console.WriteLine(info.ImageWidth); Console.Read(); }
/// <summary> /// Called when a image is finished. /// </summary> /// <param name="e"> /// The e. /// </param> protected virtual void OnImageFinished(ImageJob <WatorWorld> e) { var handler = this.ImageFinished; if (handler != null) { handler(this, e); } }
public void TestImageInfo() { var j = new ImageJob(ImageBuilderTest.GetBitmap(100, 200), null); c.CurrentImageBuilder.Build(j); Assert.AreEqual(j.SourceWidth, 100); Assert.AreEqual(j.SourceHeight, 200); Assert.AreEqual(j.ResultFileExtension, "jpg"); Assert.AreEqual(j.ResultMimeType, "image/jpeg"); }
/// <summary> /// This is inherently flawed - the unpredictability and inconsistency of disk and NTFS performance makes these results difficult to read. /// </summary> public static BenchmarkRunner <ImageJob, JobProfiler> BenchmarkFileToFile(Config c, string source, string dest, Instructions instructions) { return(BenchmarkJob(() => { var job = new ImageJob(source, dest, new Instructions(instructions)); job.DisposeDestinationStream = true; job.DisposeSourceObject = true; return job; }, c)); }
protected override RequestedAction BuildJob(ImageJob job) { if (job.Profiler != null && job.Profiler.Active) { CallContext.LogicalSetData(Key, job.Profiler); } start("job [isolate]"); return(base.BuildJob(job)); }
protected virtual void ResizeImage(HttpPostedFileBase sourceFile, string targetFolder, string targetName, Instructions settings) { var target = string.Format("~{0}/{1}", targetFolder, targetName); ImageJob job = new ImageJob(sourceFile, target, settings); job.CreateParentDirectory = true; job.Build(); }
private void resizePhoto(Stream fileStream, string path) { using (FileStream destStream = new FileStream(path, System.IO.FileMode.Create)) { ResizeSettings rs = new ResizeSettings("maxwidth=1024&maxheight=768"); ImageResizer.ImageJob job = new ImageJob(fileStream, destStream, rs); job.Build(); } }
/// <summary> /// Generates an resized image of the original in WebP format (quicker, smaller files). /// </summary> /// <param name="image">The Image the new file should be generated for. Used for logging purposes.</param> /// <param name="originalImage">The byte array for the original image.</param> /// <param name="imageFileSpec">The name of the image file specification to base the new image.</param> /// <returns>A new image stream for the resized image</returns> private static async Task <Stream> GenerateImageAsync(Image image, byte[] originalImage, ImageFileSpec imageFileSpec) { var stopwatch = new Stopwatch(); stopwatch.Start(); using (var job = new ImageJob()) { var buildNode = job.Decode(originalImage); var resampleHints = new ResampleHints(); if (imageFileSpec.FileSpecFormat != FileSpecFormat.WebPLossless && imageFileSpec.SharpeningAmount > 0) { resampleHints.SetSharpen(imageFileSpec.SharpeningAmount, SharpenWhen.Downscaling).SetResampleFilters(imageFileSpec.InterpolationFilter, null); } buildNode = buildNode.ConstrainWithin(imageFileSpec.PixelLength, imageFileSpec.PixelLength, resampleHints); IEncoderPreset encoderPreset; if (imageFileSpec.FileSpecFormat == FileSpecFormat.WebPLossless) { encoderPreset = new WebPLosslessEncoder(); } else if (imageFileSpec.FileSpecFormat == FileSpecFormat.WebPLossy) { encoderPreset = new WebPLossyEncoder(imageFileSpec.Quality); } else { encoderPreset = new MozJpegEncoder(imageFileSpec.Quality, true); } var result = await buildNode .EncodeToBytes(encoderPreset) .Finish() .SetSecurityOptions(new SecurityOptions() .SetMaxDecodeSize(new FrameSizeLimit(99999, 99999, 200)) .SetMaxFrameSize(new FrameSizeLimit(99999, 99999, 200)) .SetMaxEncodeSize(new FrameSizeLimit(99999, 99999, 200))) .InProcessAsync(); var newImageBytes = result.First.TryGetBytes(); if (newImageBytes.HasValue) { var newStream = new MemoryStream(newImageBytes.Value.ToArray()); stopwatch.Stop(); _log.Information($"LB.PhotoGalleries.Worker.Program.GenerateImageAsync() - Image {image.Id} and spec {imageFileSpec} done. Elapsed time: {stopwatch.ElapsedMilliseconds}ms"); return(newStream); } } stopwatch.Stop(); _log.Warning($"LB.PhotoGalleries.Worker.Program.GenerateImageAsync() - Couldn't generate new image for {image.Id}! Elapsed time: {stopwatch.ElapsedMilliseconds}ms"); return(null); }
public async void TestPresets() { using (var contentRoot = new TempContentRoot() .AddResource("images/fire.jpg", "TestFiles.fire-umbrella-small.jpg")) { var hostBuilder = new HostBuilder() .ConfigureWebHost(webHost => { // Add TestServer webHost.UseTestServer(); webHost.Configure(app => { app.UseImageflow(new ImageflowMiddlewareOptions() .SetMapWebRoot(false) // Maps / to ContentRootPath/images .MapPath("/", Path.Combine(contentRoot.PhysicalPath, "images")) .AddPreset(new PresetOptions("tiny", PresetPriority.OverrideQuery) .SetCommand("width", "2") .SetCommand("height", "1")) .AddPreset(new PresetOptions("small", PresetPriority.DefaultValues) .SetCommand("width", "30") .SetCommand("height", "20")) ); }); }); // Build and start the IHost using var host = await hostBuilder.StartAsync(); // Create an HttpClient to send requests to the TestServer using var client = host.GetTestClient(); using var presetValidResponse = await client.GetAsync("/fire.jpg?preset=small&height=35&mode=pad"); presetValidResponse.EnsureSuccessStatusCode(); var responseBytes = await presetValidResponse.Content.ReadAsByteArrayAsync(); var imageResults = await ImageJob.GetImageInfo(new BytesSource(responseBytes)); Assert.Equal(30, imageResults.ImageWidth); Assert.Equal(35, imageResults.ImageHeight); using var presetTinyResponse = await client.GetAsync("/fire.jpg?preset=tiny&height=35"); presetTinyResponse.EnsureSuccessStatusCode(); responseBytes = await presetTinyResponse.Content.ReadAsByteArrayAsync(); imageResults = await ImageJob.GetImageInfo(new BytesSource(responseBytes)); Assert.Equal(2, imageResults.ImageWidth); Assert.Equal(1, imageResults.ImageHeight); await host.StopAsync(CancellationToken.None); } }
private static Maybe<ImageJob> TryProcessImageJob(ImageJob oldImageJob) { return from timeSpan in TryGetTimeSpan(oldImageJob) select new ImageJob { OriginalFilePath = oldImageJob.OriginalFilePath, SliceImagePath = oldImageJob.SliceImagePath, SnapshotTimestamp = timeSpan, }; }
/// <summary> /// Builds an FIBitmap from the stream and job.Settings /// </summary> /// <param name="s"></param> /// <param name="job"></param> /// <returns></returns> protected FIBITMAP buildFiBitmap(ref FIBITMAP original, ImageJob job, bool supportsTransparency, bool mayUnloadOriginal) { ResizeSettings settings = job.Settings; if (original.IsNull) return FIBITMAP.Zero; FIBITMAP final = FIBITMAP.Zero; //Find the image size Size orig = new Size((int)FreeImage.GetWidth(original), (int)FreeImage.GetHeight(original)); //Calculate the new size of the image and the canvas. ImageState state = new ImageState(settings, orig, true); c.CurrentImageBuilder.Process(state); RectangleF imageDest = PolygonMath.GetBoundingBox(state.layout["image"]); if (imageDest.Width != orig.Width || imageDest.Height != orig.Height) { //Rescale bool temp; final = FreeImage.Rescale(original, (int)imageDest.Width, (int)imageDest.Height, FreeImageScalingPlugin.ParseResizeAlgorithm(settings["fi.scale"], FREE_IMAGE_FILTER.FILTER_BOX, out temp)); if (mayUnloadOriginal) FreeImage.UnloadEx(ref original); if (final.IsNull) return FIBITMAP.Zero; } else { final = original; } RGBQUAD bgcolor = default(RGBQUAD); bgcolor.Color = settings.BackgroundColor; if (settings.BackgroundColor == Color.Transparent && !supportsTransparency) bgcolor.Color = Color.White; //If we need to leave padding, do so. BoxPadding outsideImage = new BoxPadding(imageDest.Left, imageDest.Top, state.destSize.Width - imageDest.Right, state.destSize.Height - imageDest.Bottom); if (outsideImage.All != 0) { var old = final; //Extend canvas final = FreeImage.EnlargeCanvas<RGBQUAD>(old, (int)outsideImage.Left, (int)outsideImage.Top, (int)outsideImage.Right, (int)outsideImage.Bottom, bgcolor.Color != Color.Transparent ? new Nullable<RGBQUAD>(bgcolor) : null, FREE_IMAGE_COLOR_OPTIONS.FICO_RGBA); if (old == original) { if (mayUnloadOriginal) { FreeImage.UnloadEx(ref original); old = original; } } else { FreeImage.UnloadEx(ref old); //'old' has the original value of 'final', which we allocated. } if (final.IsNull) return FIBITMAP.Zero; } return final; }
/// <summary> /// Adds alternate pipeline based on WIC. Invoked by &builder=wic. /// This method doesn't handle job.DisposeSource or job.DesposeDest or settings filtering, that's handled by ImageBuilder. /// Handles all the work for turning 'source' into a byte[]/long pair. /// </summary> /// <param name="job"></param> /// <returns></returns> protected override RequestedAction BuildJob(ImageJob job) { if (!"wic".Equals(job.Settings["builder"])) return RequestedAction.None; //Convert the source stream to a byte[] array and length. byte[] data = null; long lData = 0; //This step gets a Stream instance, copies it to a MemoryStream, then accesses the underlying buffer to get the byte[] and length we need. Stream s = null; bool disposeStream = !(job.Source is Stream); long originalPosition = 0; bool restoreStreamPosition = false; try { //Get a Stream instance for the job string path; s = c.CurrentImageBuilder.GetStreamFromSource(job.Source, job.Settings, ref disposeStream, out path, out restoreStreamPosition); if (s == null) return RequestedAction.None; //We don't support the source object! if (job.ResetSourceStream) restoreStreamPosition = true; job.SourcePathData = path; //Save the original stream positione originalPosition = (restoreStreamPosition) ? s.Position : -1; data = StreamExtensions.CopyOrReturnBuffer(s, out lData,false, 0x1000); } finally { if (s != null && restoreStreamPosition && s.CanSeek) s.Seek(originalPosition, SeekOrigin.Begin); if (disposeStream) s.Dispose(); } //Ok, now we have our byte[] and length. //Let's find out if transparency is supported. IEncoder managedEncoder = c.Plugins.GetEncoder(job.Settings, job.SourcePathData); bool supportsTransparency = managedEncoder.SupportsTransparency; RequestedAction result = BuildJobWic(data, lData, job, supportsTransparency); GC.KeepAlive(data); return result; }
private static ImageJob ProcessImageJob( ImageJob oldImageJob, ICollection<string> remainingSnapshotPaths ) { var newSnapshotPaths = new List<string>(); foreach (var oldSnapshotPath in oldImageJob.ImageSnapshots) { if (remainingSnapshotPaths.Contains(oldSnapshotPath)) { newSnapshotPaths.Add(oldSnapshotPath); } } return new ImageJob { OriginalFilePath = oldImageJob.OriginalFilePath, SliceImagePath = oldImageJob.SliceImagePath, SnapshotTimestamp = oldImageJob.SnapshotTimestamp, ImageSnapshots = newSnapshotPaths.ToArray(), }; }
/// <summary> /// Decodes the image in byte[] data, performs the image proccessing, and encodes it to job.Dest /// </summary> /// <param name="data">The buffer containing the encoded image file</param> /// <param name="lData">The number of bytes to read</param> /// <param name="job"></param> /// <param name="supportsTransparency"></param> /// <returns></returns> protected virtual RequestedAction BuildJobWic(byte[] data, long lData, ImageJob job, bool supportsTransparency) { ResizeSettings settings = job.Settings; ResizeSettings q = settings; string path = job.SourcePathData; //A list of COM objects to destroy List<object> com = new List<object>(); try { //Create the factory IWICComponentFactory factory = (IWICComponentFactory)new WICImagingFactory(); com.Add(factory); //Wrap the byte[] with a IWICStream instance var streamWrapper = factory.CreateStream(); streamWrapper.InitializeFromMemory(data, (uint)lData); com.Add(streamWrapper); var decoder = factory.CreateDecoderFromStream(streamWrapper, null, WICDecodeOptions.WICDecodeMetadataCacheOnLoad); com.Add(decoder); //Figure out which frame to work with int frameIndex = 0; if (!string.IsNullOrEmpty(q["page"]) && !int.TryParse(q["page"], NumberStyles.Number, NumberFormatInfo.InvariantInfo, out frameIndex)) if (!string.IsNullOrEmpty(q["frame"]) && !int.TryParse(q["frame"], NumberStyles.Number, NumberFormatInfo.InvariantInfo, out frameIndex)) frameIndex = 0; //So users can use 1-based numbers frameIndex--; if (frameIndex > 0) { int frameCount = (int)decoder.GetFrameCount(); //Don't let the user go past the end. if (frameIndex >= frameCount) frameIndex = frameCount - 1; } IWICBitmapFrameDecode frame = decoder.GetFrame((uint)Math.Max(0,frameIndex)); com.Add(frame); WICBitmapInterpolationMode interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeFant; if ("nearest".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor; if ("bicubic".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeCubic; if ("linear".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeLinear; if ("nearestneighbor".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase)) interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeLinear; //Find the original image size uint origWidth, origHeight; frame.GetSize(out origWidth,out origHeight); Size orig = new Size((int)origWidth,(int)origHeight); Guid pixelFormat; frame.GetPixelFormat(out pixelFormat); //Calculate the new size of the image and the canvas. ImageState state = new ImageState(settings, orig, true); c.CurrentImageBuilder.Process(state); Rectangle imageDest = PolygonMath.ToRectangle(PolygonMath.GetBoundingBox(state.layout["image"])); IWICBitmapSource imageData = frame; //Are we cropping? then daisy-chain a clipper if (state.copyRect.Left != 0 || state.copyRect.Top != 0 || state.copyRect.Width != state.originalSize.Width || state.copyRect.Height != state.originalSize.Height) { //Cropping is absurdly slow... 4x slower than resizing! //Cropping after resizing (unintuitively) is faster. if (imageDest.Width != state.originalSize.Width || imageDest.Height != state.originalSize.Height) { double sx = (double)imageDest.Width / (double)state.copyRect.Width; double sy = (double)imageDest.Height / (double)state.copyRect.Height; uint uncroppedDestWidth = (uint)Math.Round(sx * state.originalSize.Width); uint uncroppedDestHeight = (uint)Math.Round(sy * state.originalSize.Height); var scaler = factory.CreateBitmapScaler(); scaler.Initialize(imageData, uncroppedDestWidth, uncroppedDestHeight, interpolationMode); com.Add(scaler); //TODO: cropping is not consistent with GDI. var clipper = factory.CreateBitmapClipper(); clipper.Initialize(scaler, new WICRect { X = (int)Math.Floor((double)state.copyRect.X * sx), Y = (int)Math.Floor((double)state.copyRect.Y * sy), Width = imageDest.Width, Height = imageDest.Height }); com.Add(clipper); imageData = clipper; } else { var clipper = factory.CreateBitmapClipper(); clipper.Initialize(imageData, new WICRect { X = (int)state.copyRect.X, Y = (int)state.copyRect.Y, Width = (int)state.copyRect.Width, Height = (int)state.copyRect.Height }); com.Add(clipper); imageData = clipper; } //If we're scaling but not cropping. }else if (imageDest.Width != state.originalSize.Width || imageDest.Height != state.originalSize.Height) { var scaler = factory.CreateBitmapScaler(); scaler.Initialize(imageData, (uint)imageDest.Width, (uint)imageDest.Height, interpolationMode); com.Add(scaler); imageData = scaler; } //Are we padding? Then we have to do an intermediate write. if (state.destSize.Width != imageDest.Width || state.destSize.Height != imageDest.Height){ byte[] bgcolor = ConversionUtils.ConvertColor(job.Settings.BackgroundColor, pixelFormat); for (int i = 0; i < bgcolor.Length; i++) bgcolor[i] = 255; //White var padder = new WicBitmapPadder(imageData, imageDest.X, imageDest.Y, state.destSize.Width - (imageDest.X + imageDest.Width), state.destSize.Height - (imageDest.Y + imageDest.Height), bgcolor, null); imageData = padder; } //Now encode imageData and be done with it... return Encode(factory, imageData, imageDest.Size, job); } finally { //Manually cleanup all the com reference counts, aggressively while (com.Count > 0) { Marshal.ReleaseComObject(com[com.Count - 1]); //In reverse order, so no item is ever deleted out from under another. com.RemoveAt(com.Count - 1); } } }
private static IEnumerable<ImageJob> UpdateImageJobs( IDictionary<ImageJobGroup, IEnumerable<string>> mapFromGroupsToSnapshots ) { foreach (var groupToSnapshots in mapFromGroupsToSnapshots) { string[] snapshots = groupToSnapshots.Value.ToArray(); ImageJobGroup group = groupToSnapshots.Key; foreach (var imageJob in group.Jobs) { var newImageJob = new ImageJob { OriginalFilePath = imageJob.OriginalFilePath, SliceImagePath = imageJob.SliceImagePath, SnapshotTimestamp = imageJob.SnapshotTimestamp, ImageSnapshots = snapshots, }; yield return newImageJob; } } }
private async static Task<string> ProcessImageJobAsync(ImageJob imageJob, string folderOfMediaFiles) { var newImageJobs = new ImageJobs { Images = new[] { imageJob }, }; var serializedNewImageJobs = JsonConvert.SerializeObject(newImageJobs); using (var rip = new GeneralProcess(RIP, string.Format("\"{0}\"", folderOfMediaFiles))) { using (var dedup = new GeneralProcess(DEDUP)) { using (var match = new GeneralProcess(MATCH)) { string ripOutput = await rip.ExecuteAsync(serializedNewImageJobs.ToMaybe()); string dedupOutput = await dedup.ExecuteAsync(ripOutput.ToMaybe()); string matchOutput = await match.ExecuteAsync(dedupOutput.ToMaybe()); MoveCompletedPhotos(matchOutput); return matchOutput; } } } }
private static IEnumerable<string> TryFindMatchingSnapshots(ImageJob imageJob) { var candidateSnapshots = imageJob.ImageSnapshots; var deducedImages = from originalImage in TryLoadImage(imageJob.OriginalFilePath) select CommonFunctions.ExecThenDispose( () => TryProcessSnapshotFromiPad(originalImage, candidateSnapshots) .Or(TryProcessSnapshotFromiPhoneSix(originalImage, candidateSnapshots)), originalImage ); return deducedImages.OrElse(Enumerable.Empty<string>()); }
/// <summary> /// Adds alternate pipeline based on FreeImage. Invoked by &builder=freeimage. /// This method doesn't handle job.DisposeSource or job.DesposeDest or settings filtering, that's handled by ImageBuilder. /// All the bitmap processing is handled by buildFiBitmap, this method handles all the I/O /// </summary> /// <param name="job"></param> /// <returns></returns> protected override RequestedAction BuildJob(ImageJob job) { if (!"freeimage".Equals(job.Settings["builder"])) return RequestedAction.None; if (!FreeImageAPI.FreeImage.IsAvailable()) return RequestedAction.None; //StringBuilder log = new StringBuilder(); //FreeImageAPI.FreeImageEngine.Message += (delegate(FREE_IMAGE_FORMAT fmt, string msg) { // log.AppendLine(msg); //}); // Variables Stream s = null; bool disposeStream = !(job.Source is Stream); long originalPosition = 0; bool restoreStreamPosition = false; //Get a Stream instance for the job string path; s = c.CurrentImageBuilder.GetStreamFromSource(job.Source, job.Settings, ref disposeStream, out path, out restoreStreamPosition); if (s == null) return RequestedAction.None; if (job.ResetSourceStream) restoreStreamPosition = true; job.SourcePathData = path; //Save the original stream positione originalPosition = (restoreStreamPosition) ? s.Position : -1; try { //What is our destination format IEncoder managedEncoder = c.Plugins.GetEncoder(job.Settings, job.SourcePathData); //Use the existing pipeline to parse the querystring //FREE_IMAGE_FORMAT destFormat = FreeImage.GetFIFFromMime(managedEncoder.MimeType); //Use the resulting mime-type to determine the output format. //This prevents us from supporting output formats that don't already have registered encoders. Good, right? bool supportsTransparency = managedEncoder.SupportsTransparency; return (RequestedAction)FreeImageDecoder.FreeImageDecoderPlugin.DecodeAndCall(s, job.Settings, delegate(ref FIBITMAP original, bool mayUnloadOriginal) { FIBITMAP b = FIBITMAP.Zero; try { //Do all the bitmap stuff in another method b = buildFiBitmap(ref original, job, supportsTransparency, mayUnloadOriginal); if (b.IsNull) return RequestedAction.None; // Try to save the bitmap if (job.Dest is string || job.Dest is Stream) { FreeImageEncoderPlugin e = new FreeImageEncoderPlugin(job.Settings, path); if (job.Dest is string) { //Make physical and resolve variable references all at the same time. job.FinalPath = job.ResolveTemplatedPath(job.Dest as string, delegate(string var) { if ("width".Equals(var, StringComparison.OrdinalIgnoreCase)) return FreeImage.GetWidth(b).ToString(); if ("height".Equals(var, StringComparison.OrdinalIgnoreCase)) return FreeImage.GetHeight(b).ToString(); if ("ext".Equals(var, StringComparison.OrdinalIgnoreCase)) return e.Extension; return null; }); //If requested, auto-create the parent directory(ies) if (job.CreateParentDirectory) { string dirName = Path.GetDirectoryName(job.FinalPath); if (!Directory.Exists(dirName)) Directory.CreateDirectory(dirName); } if (!FreeImage.Save(e.Format, b, job.FinalPath, e.EncodingOptions)) return RequestedAction.None; } else if (job.Dest is Stream) { if (!FreeImage.SaveToStream(b, (Stream)job.Dest, e.Format, e.EncodingOptions)) return RequestedAction.None; } } else if (job.Dest == typeof(Bitmap)) { job.Result = FreeImage.GetBitmap(b); } else return RequestedAction.None; return RequestedAction.Cancel; } finally { if (!b.IsNull && b != original) FreeImage.UnloadEx(ref b); } }); } finally { if (s != null && restoreStreamPosition && s.CanSeek) s.Seek(originalPosition, SeekOrigin.Begin); if (disposeStream) s.Dispose(); } }
protected override RequestedAction BuildJob(ImageJob job) { if (!"wpf".Equals(job.Settings["builder"])) return RequestedAction.None; // Estrazione delle ResizeSettings ResizeSettings settings = job.Settings; Stream s = null; bool disposeStream = !(job.Source is Stream); long originalPosition = 0; bool restoreStreamPosition = false; string path; s = c.CurrentImageBuilder.GetStreamFromSource(job.Source, job.Settings, ref disposeStream, out path, out restoreStreamPosition); if (s == null) return RequestedAction.None; //We don't support the source object! if (job.ResetSourceStream) restoreStreamPosition = true; job.SourcePathData = path; // Instanzio uno stream locale per le operazioni WPF using (MemoryStream localStream = (s is MemoryStream) ? (MemoryStream)s : StreamExtensions.CopyToMemoryStream(s)) { if (s != null && restoreStreamPosition && s.CanSeek) s.Seek(originalPosition, SeekOrigin.Begin); if (disposeStream) s.Dispose(); /* ? ? ? */ IEncoder managedEncoder = c.Plugins.GetEncoder(job.Settings, job.SourcePathData); bool supportsTransparency = managedEncoder.SupportsTransparency; // Recupero le dimensioni originali var frame = BitmapFrame.Create(StreamExtensions.CopyToMemoryStream(localStream)); System.Windows.Size originalSize = new System.Windows.Size(frame.PixelWidth, frame.PixelHeight); // Resetto lo stream locale alla posizione iniziale, dopo aver letto i metadata localStream.Position = 0; // Uhm... sono costretto a referenziare le System.Drawing (GDI) per questo, // TODO: chiedere al tipo se si può prevedere un costruttore di ImageState che non preveda un System.Drawing.Size come parametro System.Drawing.Size orig = new System.Drawing.Size((int)originalSize.Width, (int)originalSize.Height); using (ImageState imageState = new ImageState(settings, orig, true)) { c.CurrentImageBuilder.Process(imageState); Rectangle imageDest = PolygonMath.ToRectangle(PolygonMath.GetBoundingBox(imageState.layout["image"])); BitmapSource finalImage; BitmapImage bi = new BitmapImage(); bi.CacheOption = BitmapCacheOption.OnLoad; bi.BeginInit(); bi.StreamSource = localStream; WpfImageSettings wpfImageSettings = imageState.WpfDestinationImageSettings(settings); bi.DecodePixelWidth = Convert.ToInt32(wpfImageSettings.DestinationImageWidth); bi.DecodePixelHeight = Convert.ToInt32(wpfImageSettings.DestinationImageHeight); bi.EndInit(); // Creation of the encoder WpfEncoderPlugin wpfEncoder = new WpfEncoderPlugin(settings, job.SourcePathData); RenderTargetBitmap final = new RenderTargetBitmap(imageState.finalSize.Width, imageState.finalSize.Height, settings.Get<int>("dpi", 96), settings.Get<int>("dpi", 96), PixelFormats.Default); DrawingVisual dv = new DrawingVisual(); using (DrawingContext dc = dv.RenderOpen()) { string ARGBBackgroundColor = String.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", wpfEncoder.MimeType.Equals("image/jpeg") ? 255 : settings.BackgroundColor.A, settings.BackgroundColor.R, settings.BackgroundColor.G, settings.BackgroundColor.B); System.Windows.Media.Brush BrushBackgroundColor = new System.Windows.Media.SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(ARGBBackgroundColor)); /* todo: verificare */ dc.DrawRectangle(BrushBackgroundColor, null, new Rect(0, 0, wpfImageSettings.DestinationImageWidth, wpfImageSettings.DestinationImageHeight)); Rect rect = new Rect(wpfImageSettings.OffsetX, wpfImageSettings.OffsetY, wpfImageSettings.DestinationImageWidth, wpfImageSettings.DestinationImageHeight); //dc.PushTransform(new RotateTransform(settings.Rotate, (double)imageState.finalSize.Width / 2, (double)imageState.finalSize.Height / 2)); dc.DrawImage(bi, rect); } final.Render(dv); finalImage = final; // Write the image to the output stream wpfEncoder.Write(finalImage, (Stream)job.Dest); } } return RequestedAction.None; }
protected virtual RequestedAction Encode(IWICComponentFactory factory, IWICBitmapSource data, Size imageSize, ImageJob job) { WicEncoderPlugin encoder = new WicEncoderPlugin(job.Settings, job.SourcePathData); //Create the IStream/MemoryStream var outputStream = new MemoryIStream(); encoder.EncodeToStream(factory, data, imageSize, outputStream); object dest = job.Dest; // Try to save the bitmap if (dest is string) { //Make physical and resolve variable references all at the same time. job.FinalPath = job.ResolveTemplatedPath(job.Dest as string, delegate(string var) { if ("ext".Equals(var, StringComparison.OrdinalIgnoreCase)) return encoder.Extension; if ("width".Equals(var, StringComparison.OrdinalIgnoreCase)) return imageSize.Width.ToString(); if ("height".Equals(var, StringComparison.OrdinalIgnoreCase)) return imageSize.Height.ToString(); return null; }); //If requested, auto-create the parent directory(ies) if (job.CreateParentDirectory) { string dirName = Path.GetDirectoryName(job.FinalPath); if (!Directory.Exists(dirName)) Directory.CreateDirectory(dirName); } using (FileStream fs = new FileStream(job.FinalPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)) { outputStream.WriteTo(fs); } } else if (dest is Stream) { outputStream.WriteTo((Stream)dest); } else return RequestedAction.None; return RequestedAction.Cancel; }