0

I've been working on migrating legacy ASP.Net/C# system to Azure. Initially just changing the minimal amount possible, but part of that is moving to updated .Net framework (2/3/3.5 => 4.7+)

Part of this is a tool which creates image previews in different sizes, watermarks some , sharpens then and then saves them.

Had a client complain the new images are way too sharpened.

After much experimenting - discovered that when I exclude the additional sharpening code (Aforge.Imaging) so none is done - the un-sharpened results of .Net 4.7.2 is WAY sharper than /Net 2

I developed copies of the program that did bare minimum - both in .Net 4.7.2 and 2.0, exact same code - and the images are drastically different.

I'm assuming something has changed within the framework ?

Is it possible to tone said sharpening down a bit ?

Basically - some sharpening is good - but it's taken it too far

Code takes a potentially unusual route to generating previews as in other areas (not in the test program) it does metadata/colour space manipulation - plus is rather old. Mostly using System.Windows.Media.Imaging

FYI imageQuality is 75 dpi is 72 imgsize is 320

The basic (not all) of the test programs :

 imageStream = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read, FileShare.Read); BitmapDecoder decoder = BitmapDecoder.Create(imageStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None); myBitmapSource = decoder.Frames[0]; 

....

 BitmapFrame myBitmapSourceFrame = (BitmapFrame)myBitmapSource; destColorContext = new ColorContext(new Uri(iccTargetProfile)); ColorContext sourceColorContext; try { sourceColorContext = myBitmapSourceFrame.ColorContexts[0]; } catch (Exception Err) {//If no inbuilt profile then default to AdobeRGB sourceColorContext = new ColorContext(new Uri(iccDefaultProfile)); ; } ColorConvertedBitmap ccb = new ColorConvertedBitmap(myBitmapSource, sourceColorContext, destColorContext, PixelFormats.Pbgra32); myBitmapSource = ccb; 

....

 double nPercent = ScalePercentage(myBitmapSource.PixelHeight, myBitmapSource.PixelWidth, imgSize, imgSize); int newHeight = Convert.ToInt16((double)myBitmapSource.PixelHeight * nPercent); int newWidth = Convert.ToInt16((double)myBitmapSource.PixelWidth * nPercent); //resize by re-drawing onto new Bitmap RenderTargetBitmap rtBitmap = new RenderTargetBitmap( newWidth /* PixelWidth */, newHeight /* PixelHeight */, imageDPI /* DpiX */, imageDPI /* DpiY */, PixelFormats.Default); DrawingVisual drawVisual = new DrawingVisual(); using (DrawingContext dc = drawVisual.RenderOpen()) { dc.DrawRectangle(new ImageBrush(myBitmapSource), null /* no pen */, new Rect(0, 0, rtBitmap.Width, rtBitmap.Height)); rtBitmap.Render(drawVisual); //WATERMARK STUFF HERE //Previous Sharpening stuff HERE List<ColorContext> colorContexts = new List<ColorContext>(); colorContexts.Add(destColorContext); //encoder JpegBitmapEncoder output = new JpegBitmapEncoder(); output.QualityLevel = imageQuality; //output.Frames.Add(BitmapFrame.Create(outFrame)); output.Frames.Add(BitmapFrame.Create(rtBitmap, null, null, new System.Collections.ObjectModel.ReadOnlyCollection<ColorContext>(colorContexts))); string endImage = folderDest + fileNameOnly; using (FileStream saveFileStream = new FileStream(endImage, FileMode.Create, FileAccess.Write)) { output.Save(saveFileStream); } 

So two pictures - unsharpened using the same code to create them....

.Net 2.0 .Net 2.0

.Net 4.7.2 .Net 4.7.2

Bothersome....

1
  • Found if I set the target .Net Framework of my 4.7.2 test project to 3.5 - it gives the unsharpened version Set Target to .Net 4 and above - gives the over-sharpened version. No other changes - just changing the target of the project. Unfortunately some other references (e.g. Azure) that I need - have a dependence for 4+ Tried setting <dependentAssembly> tags in app.config while still targetting 4.7.2 - but doesn't seem to work. Commented Nov 1, 2022 at 22:39

1 Answer 1

0

Tried using assembly redirects to the older versions - but either that wouldn't work or cause more errors.

Fount out it was the RenderTargetBitmap causing it. I tried resizing using TransformedBitmap instead and that worked great! But I needed RenderTargetBitmap to do additional things (draw in a watermark).

So my eventual workaround was to use both TransformedBitmap initially to resize the original image, then RenderTargetBitmap to draw watermark on top. i.e. use TransformedBitmap to resize and pass the output of that to RenderTargetBitmap instead of the original BitmapSource

So main part became : (myBitmapSource is original image)

 double nPercent = ScalePercentage(myBitmapSource.PixelHeight,myBitmapSource.PixelWidth, maxHeight, maxWidth); int newHeight = Convert.ToInt16((double)myBitmapSource.PixelHeight * nPercent); int newWidth = Convert.ToInt16((double)myBitmapSource.PixelWidth * nPercent); //resize by re-drawing onto new Bitmap RenderTargetBitmap rtBitmap = new RenderTargetBitmap( newWidth /* PixelWidth */, newHeight /* PixelHeight */, imageDPI /* DpiX */, imageDPI /* DpiY */, PixelFormats.Default); //new resizing TransformedBitmap tranBitmap = new TransformedBitmap(myBitmapSource, new ScaleTransform(nPercent, nPercent)); DrawingVisual drawVisual = new DrawingVisual(); using (DrawingContext dc = drawVisual.RenderOpen()) { //dc.DrawRectangle(new ImageBrush(myBitmapSource), null /* no pen */, new Rect(0, 0, rtBitmap.Width, rtBitmap.Height)); dc.DrawImage(tranBitmap, new Rect(0, 0, rtBitmap.Width, rtBitmap.Height)); //watermarking code......... } rtBitmap.Render(drawVisual); //then some colour context/profile stuff prepared before List<ColorContext> colorContexts = new List<ColorContext>(); colorContexts.Add(destColorContext); //saving (simplified) JpegBitmapEncoder output = new JpegBitmapEncoder(); output.QualityLevel = imageQuality; output.Frames.Add(BitmapFrame.Create(writeBitmap, null, null, new System.Collections.ObjectModel.ReadOnlyCollection<ColorContext>(colorContexts))); //Saving to memory stream and then copy to File Steam 

It's not quite like the .Net 3.5 unsharpened output - is a little sharper - but MUCH better than over sharpened 4.7.2 code.

New output (without additional sharpening) New output (without additional sharpening)

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.