Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Picture box, square and rectangular pixels?

Status
Not open for further replies.

tedsmith

Programmer
Nov 23, 2000
1,762
AU
I wrote a little program to quickly crop and convert any pixel size JPG taken on a 3x4 digital still camera to widescreen 16x9 BMP's of exactly the same pixel as my home videos.If you do this, stills integrate with the video without the problems you often get trying to mix different resolution or compression material in video editing and it is such a pain converting each one exactly in Photoshop. The BMP quality of the final result is just as good in every way as the original jpg when viewed on a computer monitor and noticeably better on the final DVD or Blue Ray compared with letting the video editor do the conversion. Also the Adobe video editor doesn't crash or run out of resources!

I load the picture to be converted to a hidden picture box, crop or magnify it, then PaintPicture this to a second hidden picture box of exactly the desired pixels, then save as a bmp while previewing it on a smaller image box with stretch - true.

Converting to 640x480 or 720x570 for 3x4 SD (standard resolution) and to 1900x1080 for full HD is perfect because they uses square pixels but when I try to convert to 720x576 wide screen (which is what all PAL SD material is these days) the quality is lower because the video editor has to reconvert it to rectangular pixels because 720x576 is not 16x9
I get a reasonable result setting the final picture box to 1024x576 (16x9) but the picture is slightly grainy with artifacts a bit like thumbnails when you magnify them because I don't have the correct number of pixels.

Question is is it possible to format in some way a picture box in rectangular pixels and save them?

 
Aspect ratios are normally written as 4/3 or 4:3, comparing width to height. Never as 3x4, or 16x9 (where you flip and flop dimensions in these examples).

As far as I know anything GDI-based (like the VB6 Form, Image, or PictureBox) "follows the hardware." If you have square pixel hardware you get square pixels.

It looks as if both PAL and NTSC formats use (different) non-square pixel aspect ratios. It also appears that people use various rule-of-thumb hacks to try to cope:

So:

To convert rectangular pixel PAL 720x576 DV to square pixel image you should scale to 788x576, then optionally crop it with 10 pixels from both sides so that the final image is 768x576.

To convert rectangular pixel NTSC 720x480 DV to square pixel image you should scale to 656x480, then optionally crop it with 8 pixels from both sides so that the final image is 640x480.

And to the other direction:

To convert a 4:3 (2048x1536, 768x576 etc) square pixel still image to PAL 720x576 rectangular pixel video, you should resample to 702x576, then pad with 9 black pixels to the sides so that the final image is 720x576.

To convert a 4:3 (2048x1536, 640x480 etc) square pixel still image to NTSC 720x480 rectangular pixel video, you should resample to 702x480, then pad with 9 black pixels to the sides so that the final image is 720x480.

All of that would seem to be trivial using WIA 2.0, which has image processing filters that are very high level wrappers around GDI+ and quite easy to use. Or you might try using the GDI+ flat API. The resulting quality ought to be improved over using VB6's GDI wrappers and GDI API calls.

GDI+ may also give you more control over horizontal and vertical DPI and support transformations between different settings.
 
You could turn those "rules" around and crop top/bottom instead of padding left/right.

Or you might "squish" if that makes more sense:

Code:
Option Explicit
'Needs reference to:
'
'   Microsoft Windows Image Acquisition Library 2.0

'Form dimensions: 10890x9030 twips, giving client area of
'                 720x576 pixels when display is at 96dpi.

Private Sub Form_Load()
    Dim img As WIA.ImageFile
    
    'Load JPEG image:
    Set img = New WIA.ImageFile
    img.LoadFile "sample.jpg"
    
    With New WIA.ImageProcess
        'Resample/scale to 720x576:
        .Filters.Add .FilterInfos!Scale.FilterID
        With .Filters(1).Properties
            !PreserveAspectRatio = False
            !MaximumWidth = 720
            !MaximumHeight = 576
        End With
        'Set desired JPEG quality:
        .Filters.Add .FilterInfos!Convert.FilterID
        With .Filters(2).Properties
            !FormatID = wiaFormatJPEG
            !Quality = 75 'Percent.
        End With
        Set img = .Apply(img)
    End With
    
    'Display result on Form just to have a look:
    Picture = img.FileData.Picture
    
    'Save as new JPEG file removing any existing file first:
    On Error Resume Next
    Kill "altered.jpg"
    On Error GoTo 0
    img.SaveFile "altered.jpg"
End Sub
 
Cropped approach instead:

Code:
Option Explicit
'Needs reference to:
'
'   Microsoft Windows Image Acquisition Library 2.0

'Form dimensions: 10890x9030 twips, giving client area of
'                 720x576 pixels when display is at 96dpi.

Private Sub Form_Load()
    Dim img As WIA.ImageFile
    
    'Load JPEG image:
    Set img = New WIA.ImageFile
    img.LoadFile "sample.jpg"
    
    With New WIA.ImageProcess
        'Resample/scale to 720x591:
        .Filters.Add .FilterInfos!Scale.FilterID
        With .Filters(1).Properties
            !PreserveAspectRatio = False
            !MaximumWidth = 720
            !MaximumHeight = 591
        End With
        'Crop 8 pixels from top, 7 pixels from bottom:
        .Filters.Add .FilterInfos!Crop.FilterID
        With .Filters(2).Properties
            !Top = 8
            !Bottom = 7
        End With
        'Set desired JPEG quality:
        .Filters.Add .FilterInfos!Convert.FilterID
        With .Filters(3).Properties
            !FormatID = wiaFormatJPEG
            !Quality = 75 'Percent.
        End With
        Set img = .Apply(img)
    End With
    
    'Display result on Form just to have a look:
    Picture = img.FileData.Picture
    
    'Save as new JPEG file removing any existing file first:
    On Error Resume Next
    Kill "altered.jpg"
    On Error GoTo 0
    img.SaveFile "altered.jpg"
End Sub
 
I only referred to aspect ratios as 3x4 and 16x9 because in specs for monitors, TV sets or photographs are often written that way. I didn't think there was any standard and it means the same thing as 4x3 and 9x16 anyway. 30 years ago I worked in the TV broadcasting industry and it was referred to differently as 3x4 and even sometimes 1.33 then.
When various film wide screens were introduced they were often expressed as a decimal number.

The same principle applies to whether it is PAL or NTSC, only the exact number of pixels is different because historically analog PAL had 12% more lines than NTSC.

I don't think it has anything to do with the hardware. The reference to square and rectangular is a bit imaginary because a pixel is just a few numbers with no actual shape. It is how they are used that gives them a 'shape'

4x3 SD has the same number of pixels (720 across) as wide screen SD but the picture is anamorphic stretched by the viewing device. Each pixel would appear rectangular if viewed normally. TVs and DVD players usually allow you to fiddle with this manually to get the picture right depending on who made the DVD.
If you made a new release of an old movie on DVD it would be silly to crop the edges as you would loose a large part of the available bandwidth. Video editors five you the option of either.

The problem with rectangular vs square pixels is that a wide screen (9x16) movie SD picture is 720 x 576 which is not the same ratio as 16 x 9. If I crop an original square pixel picture (4x3) to 768x576 pixels then show it on stretched wide screen (which what wide screen SD is), it looks badly horizontally squashed. It would have to be 1024 x576 to see it properly when mixed with other video material (when I want to include a 'still slide' taken on a still camera in my movie).

What I need is a routine that takes the 1024 pixels and scales the same info contained in these pixels to 720 pixels by some sort of an averaging method. While I could use the video editor to convert in a limited way, this uses a lot of resources particularly in a long movie with many stills so I wanted to convert to the same as a video frame before adding them to the video clip line. Video forums are full of posts complaining their editor crashes when they try to make a large "DVD slide show".
 
I think this does what you are describing: take a wide image 1024x576 and scale it to 720x576. Same code as above but with minor changes to a few constants.

Code:
Option Explicit
'Needs reference to:
'
'   Microsoft Windows Image Acquisition Library 2.0

'Form dimensions: 10890x9030 twips, giving client area of
'                 720x576 pixels when display is at 96dpi.

Private Sub Form_Load()
    Dim img As WIA.ImageFile
    
    'Load JPEG 1024x576 image:
    Set img = New WIA.ImageFile
    img.LoadFile "wide.jpg"
    
    With New WIA.ImageProcess
        'Resample/scale to 720x576:
        .Filters.Add .FilterInfos!Scale.FilterID
        With .Filters(1).Properties
            !PreserveAspectRatio = False
            !MaximumWidth = 720
            !MaximumHeight = 576
        End With
        'Set desired JPEG quality:
        .Filters.Add .FilterInfos!Convert.FilterID
        With .Filters(2).Properties
            !FormatID = wiaFormatJPEG
            !Quality = 80 'Percent.
        End With
        Set img = .Apply(img)
    End With
    
    'Display result on Form just to have a look:
    Picture = img.FileData.Picture
    
    'Save as new JPEG file removing any existing file first:
    On Error Resume Next
    Kill "sqashed.jpg"
    On Error GoTo 0
    img.SaveFile "sqashed.jpg"
End Sub

At least it seems to do the job. I can open the output file in IrfanView and resize/resample to 1024 pixels wide and get back a picture that looks normal.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top