Click here to Skip to main content
11,578,954 members (62,761 online)
Click here to Skip to main content

A C# MPEG1 Image Compression Class

, 22 Jan 2004 180K 5.7K 53
Rate this:
Please Sign up or sign in to vote.
This article shows how to compress an image using the MPEG1 format

Introduction

There is a lot of support in C# for image conversion and compression, but I have never found a good tool to convert images into the MPEG format. I wish someone had done it for me, but since they didn't I wrote a class called MPEGFunctions that provides the functions you need to convert a bitmap image to an MPEG1 I Frame. The code is functional but definitely not optimized or efficient. I think the MPEGFunctions class and the provided sample application are a pretty good learning tool if you want to learn more about MPEG image compression.

There are a couple reasons why I needed a program like this. The first is that I have some MPEG animations on my web site, and I wanted to put up a short title screen at the beginning of the video clips. I can create a title screen using something like Microsoft Paint, convert it to an MPEG sequence of 2 second duration, and then play it with Windows Media Player (Media Player won't display JPEGs but will display my MPEG sequences). Another reason is I work with digital set top boxes, and I needed a way to create MPEG still frames that the boxes could display. Set top boxes are good at rendering MPEG but usually can't display JPEGs.

Background

The MPEG1 standard (ISO/IEC 11172 Part 2) describes the process used to encode and compress an image into the MPEG1 format. A good tutorial link I found on the web that helped me a lot can be found here:

or do a Google search on: jpeg dct cmpt365.

The source code for the MPEGFunctions class is in the file named Class1.cs. The source code for the ImageFunctions class is in the ImageFunctions.cs file.

The simplest MPEG frame type is the I Frame. To convert an image to an MPEG I Frame you need to start with an RGB bitmap and go through the following steps:

  1. Pad the bitmap in both the height and width dimensions so that the bitmap dimensions are even multiples of 16. You need to do this because the basic building block of an MPEG image is a 16x16 pixel macro block. Use the ImageFunctions.padWidth and ImageFunctions.padHeight functions.
  2. Break the image into 16x16 pixel macro blocks.
  3. For each macroblock create 4 8x8 pixel Y blocks, and sub sample the macro block to create 1 8x8 pixel CR block and 1 8x8 pixel CBblock. Convert the RGB values for the pixels into Y, CR, and CB color components. Use the MPEGFunctions.getYMatrix, MPEGFunctions.getCRMatrix, and MPEGFunctions.getCBMatrix functions.
  4. Calculate the Discrete Cosine Transform (DCT) for each block. Use the MPEGFunctions.calculateDCT function.
  5. Quantize the DCT coefficients. Use the MPEGFunctions.Quantize function.
  6. Rearrange the DCT coefficients for each block using a zigzag scan. Use the MPEGFunctions.Zigzag function.
  7. Calculate the Huffman Code sequences for the DC DCT coefficients. Use the MPEGFunctions.DCHuffmanEncode function.
  8. Calculate the Huffman Code sequences for the AC DCT coefficients. Use the MPEGFunctions.ACHuffmanEncode function.
  9. Repeat steps 3 through 8 for each macro block in the image.
  10. Write the MPEG headers, Huffman Codes, and MPEG trailers to a memory stream, file, or other output format.

Using the code

The sample application shows how to use the MPEGFunctions class.

  • Use File->Open to select any C# supported image format (GIF, JPEG, BMP, etc.). The image will be placed into pictureBox1. If the image is smaller than 352x352 pixels it will be displayed at its normal size. If it is bigger, it will be stretched/squeezed to fit in the 352x352 picture box. The image will be padded if necessary to make the dimensions evenly divisible by 16.
  • If you select WriteToFile->MPEG IFrame the image will be converted to an MPEG1 IFrame and written to the selected output file. You can open the output file with Windows Media Player and it will display.
  • If you select WriteToFile->MPEG Sequence the image will be converted to an IFrame. The converted image will be repeated for the number of frames selected in the dialog box. The entire sequence will be written to the selected output file. You can open the output file with Windows Media Player and it will play at a rate of 30 frames per second.
  • If you click on a location in pictureBox1 the associated 16x16 pixel macroblock will be displayed in pictureBox2. The macroblock is stretched to fit the pictureBox2 dimensions.
  • If you select the "Block Details" button you will be taken to a new dialog box where you can see the R, G, and B pixel values for the macroblock.
  • If you select the "Convert To YPrPb" button you will be taken to a new dialog box where you can see the Y, Pr, and Pb values for the macroblock.
  • If you select the "Calculate DCT" button you will be taken to a new dialog box where the DCT transformed values for the selected block will be displayed.
  • If you select the "Quantize" button you can see the results of the quantization step.
  • If you select the "ZigZag Order" button you can see the results of reordering the DCT coefficients.
  • If you select "DC Encode" you can see the binary string produced by Huffman encoding the DC value.
  • If you select "AC Encode" you can see the binary string produced by Huffman encoding the AC values.

Points of Interest

MPEG I Frames are very similar to JPEG images, in fact the process to create a JPEG is virtually identical to MPEG. The syntax of the final bitstream is different, but with some simple changes you could turn the MPEGFunctions class into a JPEGFunctions class. However, in C# it is so simple to save images as JPEGs that it really isn't necessary. You can see how simple it is to convert a bitmap to JPEG in my sample application in the UserControl1.WriteJPEG function.

MPEG is not really designed to be a format for single image compression. It is actually supposed to be used for video compression, and a lot of its usefulness comes from using previous and future video frames to make predictions for what any single video frame will look like. These are called P and B frames and allow video to be compressed even more efficiently than if only I Frames are used.

Conclusion

So far I can only do MPEG I frames, but I hope to keep going with this project and add the functions needed to create MPEG P and B frames. I will also create a JPEGFunctions class someday that is similar to the MPEGFunctions class. Hopefully in 3 months or so there will be an update to this project.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Mike Donovan
Engineer
United States United States
I hold the Division 1 record for most hours slept in a college semester.

You may also be interested in...

Comments and Discussions

 
SuggestionBugfix and optimizations Pin
Member 1012304426-May-14 2:37
memberMember 1012304426-May-14 2:37 
GeneralRe: Bugfix and optimizations Pin
jfriedman13-Jun-14 9:40
professionaljfriedman13-Jun-14 9:40 
GeneralMy vote of 5 Pin
jfriedman30-Oct-12 15:59
memberjfriedman30-Oct-12 15:59 
Questioncompressing image to save space in DB and avoid slow of dataflow in a network Pin
Member 876485727-Mar-12 6:11
memberMember 876485727-Mar-12 6:11 
GeneralDecompression Pin
Mylumca18-Feb-09 23:33
memberMylumca18-Feb-09 23:33 
Generalimage decompression Pin
Mylumca18-Feb-09 23:31
memberMylumca18-Feb-09 23:31 
QuestionCan you implements the MPEG4 Image Compression Class in CSharp Pin
Member 467890419-Aug-08 18:40
memberMember 467890419-Aug-08 18:40 
GeneralAVI TO MPEG Pin
pratik_at_work3-Feb-08 18:47
memberpratik_at_work3-Feb-08 18:47 
GeneralHard coded frame rate Pin
samjindal18-Oct-07 0:08
membersamjindal18-Oct-07 0:08 
Generalmpeg format Pin
cua14-May-07 23:09
membercua14-May-07 23:09 
GeneralDirectShow.NET Pin
BarryDorman15-Feb-07 11:08
memberBarryDorman15-Feb-07 11:08 
QuestionReal time vedio capturing Pin
Member #248359411-Feb-07 18:06
memberMember #248359411-Feb-07 18:06 
QuestionFrame and Compression Rates Pin
Richard Moult10-Jan-07 5:44
memberRichard Moult10-Jan-07 5:44 
GeneralThanx Mike Pin
junaid10911-Oct-06 1:43
memberjunaid10911-Oct-06 1:43 
Generalmedia player Pin
xenia gr3-Sep-06 22:39
memberxenia gr3-Sep-06 22:39 
GeneralHELP Pin
hghgc31-Aug-06 20:42
memberhghgc31-Aug-06 20:42 
GeneralSequence Pin
Kladrian9-Jul-06 7:20
memberKladrian9-Jul-06 7:20 
GeneralRe: Sequence Pin
Usman Syed18-Dec-06 22:05
memberUsman Syed18-Dec-06 22:05 
GeneralRe: Sequence Pin
samjindal22-Oct-07 22:32
membersamjindal22-Oct-07 22:32 
QuestionBroken exe file ? Pin
m0w31-Mar-06 3:58
memberm0w31-Mar-06 3:58 
Questionhow to build dll file? Pin
uumeme2-Feb-06 4:57
memberuumeme2-Feb-06 4:57 
GeneralResolution of the image is changed Pin
jjohn200526-Jan-06 23:10
memberjjohn200526-Jan-06 23:10 
GeneralMultiple BMPs Pin
Lego21-Oct-04 3:12
memberLego21-Oct-04 3:12 
Questionhow to write data in jpeg Pin
Anonymous9-Sep-04 21:44
sussAnonymous9-Sep-04 21:44 
GeneralNice work Pin
Ronnie Wulfsohn2-May-04 6:41
memberRonnie Wulfsohn2-May-04 6:41 
QuestionHow Can I change From MPEG Fuctions to JPEG Functions Pin
DevXII1-May-04 0:17
sussDevXII1-May-04 0:17 
GeneralGot Confused!!! Pin
DEV0530-Apr-04 23:12
sussDEV0530-Apr-04 23:12 
Generalmpeg-1 Pin
niveen419-Apr-04 7:30
memberniveen419-Apr-04 7:30 
GeneralRe: mpeg-1 Pin
JOHALEMED15-Aug-07 11:46
memberJOHALEMED15-Aug-07 11:46 
GeneralSweet Work Pin
Jacob Slusser23-Jan-04 15:28
memberJacob Slusser23-Jan-04 15:28 
GeneralRe: Sweet Work Pin
geragonz27-Jan-04 13:01
membergeragonz27-Jan-04 13:01 
GeneralActually wmplayer supports JPG and GIF Pin
WongYok23-Jan-04 1:50
memberWongYok23-Jan-04 1:50 
Questionpointless....? Pin
geragonz21-Jan-04 8:45
membergeragonz21-Jan-04 8:45 
AnswerRe: pointless....? Pin
Colin Angus Mackay22-Jan-04 23:39
memberColin Angus Mackay22-Jan-04 23:39 
GeneralRe: pointless....? Pin
geragonz23-Jan-04 10:17
membergeragonz23-Jan-04 10:17 
GeneralRe: pointless....? Pin
Colin Angus Mackay23-Jan-04 10:24
memberColin Angus Mackay23-Jan-04 10:24 
GeneralRe: pointless....? Pin
geragonz27-Jan-04 12:58
membergeragonz27-Jan-04 12:58 
GeneralRe: pointless....? Pin
Peter Hancock2-Nov-05 13:51
memberPeter Hancock2-Nov-05 13:51 
GeneralRe: pointless....? Pin
manu_andre26-Jan-06 17:08
membermanu_andre26-Jan-06 17:08 
GeneralRe: pointless....? Pin
geragonz27-Jan-06 14:54
membergeragonz27-Jan-06 14:54 
GeneralRe: pointless....? Pin
manu_andre31-Jan-06 14:35
membermanu_andre31-Jan-06 14:35 
GeneralRe: pointless....? Pin
loneferret20-Aug-06 2:24
memberloneferret20-Aug-06 2:24 
AnswerRe: pointless....? Pin
auld29-Mar-07 22:08
memberauld29-Mar-07 22:08 
AnswerRe: pointless....? Pin
sajuvn29-Nov-06 17:14
membersajuvn29-Nov-06 17:14 
GeneralMPEG2 Comparision Pin
boka14-Jan-04 2:30
memberboka14-Jan-04 2:30 
GeneralRe: MPEG2 Comparision Pin
frederikgodejohann@gmx.de24-Sep-04 1:21
memberfrederikgodejohann@gmx.de24-Sep-04 1:21 
GeneralMPEG1/2 Information Pin
Alexander M.13-Jan-04 8:02
memberAlexander M.13-Jan-04 8:02 
GeneralMPEG1-still is just JPEG Pin
Stephane Rodriguez.13-Jan-04 6:12
memberStephane Rodriguez.13-Jan-04 6:12 
GeneralRe: MPEG1-still is just JPEG Pin
auld29-Mar-07 22:33
memberauld29-Mar-07 22:33 
QuestionInteresting, but flawed? Pin
dog_spawn13-Jan-04 3:30
memberdog_spawn13-Jan-04 3:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150603.1 | Last Updated 23 Jan 2004
Article Copyright 2004 by Mike Donovan
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid