qwert

Perplexed by JPG conversion result

19 posts in this topic

#1 ·  Posted

I've been trying to determine the proper calls and parameters available for JPG conversions (mainly, scaling and image quality).  But I've run into a result from a very basic conversion that has me baffled.  Using a simple example I found, I can control the quality of the result (e.g., 80%, 90%, etc).  But something is altering the colors and I can't determine what setting is involved.

The example, below, shows the results I'm seeing.  All 21 lines of the related conversion code is shown on the captured screen.

I will greatly appreciate if someone can point out the problem parameter or missing assignment ... or to a suitable example of how to save with quality=100.

Thanks in advance for any help.

Perplexing Result.png

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I've isolated the very simplest test case (below) that gives the "transformed" result that I'm seeing.  And I've examined everything I can think of in the ScreenCapture UDF.

I will greatly appreciate if someone explain how to capture a portion of the screen to a JPG file so that the file contains exactly what's on the screen (... or explain why it's not possible.)

;       Minimum Capture Sequence
#include <ScreenCapture.au3>

_ScreenCapture_Capture(@ScriptDir & "\capturedX.jpg", 4, 94, 400, 200)
MsgBox(0, "Result", "Done")

BTW, the help file says the default quality = 100 and I've tried it with and without that setting/call.

 

Simple Capture.PNG

 

Edited by qwert

Share this post


Link to post
Share on other sites

#3 ·  Posted

The highlightning of the current source line in Scite seems to be an artifact due to Scite internals AFAICT.

To avoid such change try selecting an item in the Scite menu and launch the capture of the text region again.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Thanks for your response.

Unfortunately, it's not the highlighting that's the problem.  It's the way colors are transformed ... plus the pixel-level fuzziness that creeps in.  (If you use MSPaint to zoom my latest example, you'll see a halo effect around the colored text.)

 

Update:  As a clarification, I changed the above example to one that doesn't have the SciTE highlight.

Edited by qwert

Share this post


Link to post
Share on other sites

#6 ·  Posted

Quote

Jpeg is a method of lossy compression.

Absolutely.  I've read dozens of pages about that aspect of the JPG format.  But here's my reality:

>> Other image editing programs can produce an essentially perfect JPG from a bitmap image.

>> My Au3 calls are producing a distinctly "less than" result.  Something in the Au3 settings is transforming the colors and quality.  What?

As an example, I've taken the image I posted above and viewed it with Faststone Image Viewer.  I set the viewer's JPG quality setting to 100% and exported the image as a JPG.  The file gets larger, as expected, but the viewed content is near perfect.  And that's the result I need from AutoIt3: near perfect, when I ask for Quality = 100.

 

Simple Capture.jpg

Share this post


Link to post
Share on other sites

#7 ·  Posted

I think it's related to this fact:

"The problem (after reading your edits) is probably due to the fact that GDI+ uses 4:1:1 subsampling for JPG files in it's default Encoder."

http://stackoverflow.com/questions/745610/how-to-disable-subsampling-with-net-gdi

Either switch to an external lib or use PNG as output format.

Share this post


Link to post
Share on other sites

#8 ·  Posted

The issue is that GDI+ enables chroma subsampling which modifies the color values accordingly.

 

#include <ScreenCapture.au3>

_GDIPlus_Startup()

Global $hGDIBitmap = _ScreenCapture_Capture("", 4, 94, 400, 200)
Global $hGDIpBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hGDIBitmap)
_WinAPI_DeleteObject($hGDIBitmap)

_GDIPlus_ImageSaveToFile($hGDIpBitmap, @ScriptDir & "\Test.bmp")
ConsoleWrite(SaveAsJPG(@ScriptDir & "\Test.jpg", $hGDIpBitmap) & @CRLF)

_GDIPlus_ImageDispose($hGDIpBitmap)
_GDIPlus_Shutdown()

ShellExecute(@ScriptDir & "\Test.jpg")
ShellExecute(@ScriptDir & "\Test.bmp")


Func SaveAsJPG($sFilename, $hImage, $iQuality = 100)
    _GDIPlus_Startup()
    Local $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
    Local $tParams = _GDIPlus_ParamInit(1)
    Local $tData = DllStructCreate("ulong Quality")
    $tData.Quality = $iQuality
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($tData))
    Local $iReturn = _GDIPlus_ImageSaveToFileEx($hImage, $sFilename, $sCLSID, DllStructGetPtr($tParams))
    Return SetError(@error, @extended, $iReturn)
EndFunc

I do not know how to disable it.


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#9 ·  Posted

Thanks to you, both.  That is new to me ... and it sounds like it has the possibility of resolving the entire issue.  A quick investigation led to these two sources:

The basic situation with chroma subsampling

A more technical view of chroma subsampling

I'll do my best to figure something out (... although my only advantage in this situation is that I'm focused on it and have some clear tests to gauge the results.)

Thanks, again.

 

Share this post


Link to post
Share on other sites

#10 ·  Posted

I may have found something.  But I don't know what to do with it.

Digging into the methods involved in JPG processing by the codec led me to this eye-opening description by Microsoft:

"let’s start by looking at how JPG images are typically encoded"

So the subsampling occurs on the YCbCr color space contents, as part of a sequence that appears to be controlled by these parameters:

Encoder Parameters.png

Does anyone see a solution in this?  To the untrained eye (me) it would seem that WICJpegYCrCbSubsampling444 = 0x00000003 needs to be an encoder parameter, just like quality = 100.  But how?

Faststone Image Viewer implements it with the programming behind its option panel:

Faststone settings.PNG

Anyone have ideas?

 

Share this post


Link to post
Share on other sites

#12 ·  Posted

Share this post


Link to post
Share on other sites

#14 ·  Posted

The COM interface "Windows Imaging Component" WIC might be another option, seems to support subsampling, but that's way over my head.

https://msdn.microsoft.com/en-us/library/windows/desktop/ee719794(v=vs.85).aspx

Maybe something for trancexx when she gets bored?

 

Share this post


Link to post
Share on other sites

#15 ·  Posted

Thanks for your responses. 

It's getting deep.  Apparently, there's an entire parallel universe of JPG processing that revolves around processing available in jpegtran.exe

jpegtran information and resources

Inventory of programs using jpegtran

An overview of the software

Current version available on Softpedia?

But, KaFu, I think you're pointing out the right direction.  For this one additional capability, it would be better to tap the WIC features that are already on most PCs.  It didn't take me long to locate WindowsCodecsExt.dll on \System32.  Yet, I have no idea what it takes to implement.

Share this post


Link to post
Share on other sites

#16 ·  Posted

Additional Considerations

As it turns out, a script for using jpegtran (and associated programs) already exists on these forums: here

I had already read about cjpeg and jhead, and will now have to consider these possibilities.  What I gather, however, is that these utilities operate on an existing JPG, which leaves the problem of how to get lossless content into the file, in the first place.

Share this post


Link to post
Share on other sites

#18 ·  Posted

This looks good for me.

#include <ScreenCapture.au3>

; https://mozjpeg.codelove.de/binaries.html
; https://mozjpeg.codelove.de/bin/mozjpeg_3.1_x86.zip

; Requires "cjpeg.exe" and "libjpeg-62.dll" in @ScriptDir

_ScreenCapture_Capture(@ScriptDir & "\screen.bmp")
Run(@ComSpec & " /c cjpeg.exe -quality 92 -rgb screen.bmp > screen.jpg", @ScriptDir, @SW_HIDE)

 

cjpeg_screenshot.zip

Share this post


Link to post
Share on other sites

#19 ·  Posted

Well done!

The example I ran gives excellent color matches.  And the JPG is 1/10 the size of the BMP.  The subtle artifacts are very much expected with quality = 92.

Below is a zoomed comparison of the BMP (top) and the JPG.  I'll continue testing with quality = 100.

Thanks for this.

 

Slight Difference.PNG

 

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now