Сжатие Цветных Изображений Jpeg

Тема в разделе "Java", создана пользователем inetic575, 2 июн 2013.

  1. inetic575

    inetic575 New Member

    Регистрация:
    2 июн 2013
    Сообщения:
    1
    Симпатии:
    0
    Задание:
    1.Описать и реализовать алгоритм сжатия цветных изображений Jpeg блоками 8х8. Код не работает. Компилировала в онлайн. Помогите разобраться пожалуйста.

    Код (Text):
     package org.jfor.jfor.tools.jpeg;
    import java.awt.Image;
    import java.awt.Component;
    import java.awt.MediaTracker;
    import java.io.BufferedOutputStream;
    import java.io.OutputStream;
    import java.io.IOException;
    import java.io.*;
    import java.net.URL;
    import java.awt.Toolkit;

    public class Encoder extends Component
    {



    private BufferedOutputStream outStream = null;
    private JpegInfo jpegObj = null;
    private Huffman huf = null;
    private DCT dct = null;

    private int quality;

    public static int[] jpegNaturalOrder =
    {
    0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27,
    20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
    58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63,
    };

    public Encoder (int quality, OutputStream out)
    {
    outStream = outStream = new BufferedOutputStream (out);
    this.quality = quality;
    }

    public void encodeJPEG (Image image) throws JPEGException
    {
    process (image);
    }

    public void encodeJPEG (URL url) throws JPEGException
    {
    Image image = Toolkit.getDefaultToolkit ().getImage (url);
    process (image);
    }


    public void encodeJPEG (byte[] data) throws JPEGException
    {
    Image image = Toolkit.getDefaultToolkit ().createImage (data);
    process (image);
    }


    private void process (Image image) throws JPEGException
    {
    MediaTracker tracker = new MediaTracker (this);
    tracker.addImage (image, 0);
    try
    {
    tracker.waitForID (0);
    }
    catch (InterruptedException e)
    {
    // Got to do something?
    }


    setQuality (quality);

    jpegObj = new JpegInfo (image);

    huf = new Huffman ();

    compress ();

    dispose ();
    }


    public int getQuality ()
    {
    return quality;
    }

    public void setQuality (int quality)
    {
    this.quality = quality;
    dct = new DCT (quality);
    }


    private void dispose ()
    {
    if (jpegObj != null)
    {
    jpegObj.dispose ();
    jpegObj = null;
    }
    if (huf != null)
    {
    huf.dispose ();
    huf = null;
    }
    if (dct != null)
    {
    dct.dispose ();
    dct = null;
    }
    }


    private void compress () throws JPEGException
    {
    WriteHeaders (outStream);
    WriteCompressedData (outStream);
    WriteEOI (outStream);

    try
    {
    outStream.flush ();
    }
    catch (IOException e)
    {
    throw new JPEGException (e);
    }
    }


    private void WriteEOI (BufferedOutputStream out)
    {
    byte[] EndOfImage =
    {
    (byte) 0xFF, (byte) 0xD9
    };

    WriteMarker (EndOfImage, out);
    }

    private void WriteHeaders (BufferedOutputStream out)
    {
    int i, j, index, offset, length;
    int tempArray[];

    // the SOI marker
    byte[] startOfImage =
    {
    (byte) 0xFF, (byte) 0xD8
    };

    WriteMarker (startOfImage, out);


    byte jFIF[] = new byte[18];

    jFIF[0] = (byte) 0xff;
    jFIF[1] = (byte) 0xe0;
    jFIF[2] = (byte) 0x00;
    jFIF[3] = (byte) 0x10;
    jFIF[4] = (byte) 0x4a;
    jFIF[5] = (byte) 0x46;
    jFIF[6] = (byte) 0x49;
    jFIF[7] = (byte) 0x46;
    jFIF[8] = (byte) 0x00;
    jFIF[9] = (byte) 0x01;
    jFIF[10] = (byte) 0x00;
    jFIF[11] = (byte) 0x00;
    jFIF[12] = (byte) 0x00;
    jFIF[13] = (byte) 0x01;
    jFIF[14] = (byte) 0x00;
    jFIF[15] = (byte) 0x01;
    jFIF[16] = (byte) 0x00;
    jFIF[17] = (byte) 0x00;

    WriteArray (jFIF, out);

    // Comment Header
    String comment = new String ();

    comment = jpegObj.getComment ();
    length = comment.length ();

    byte cOM[] = new byte[length + 4];

    cOM[0] = (byte) 0xFF;
    cOM[1] = (byte) 0xFE;
    cOM[2] = (byte) ((length >> 8) & 0xFF);
    cOM[3] = (byte) (length & 0xFF);

    java.lang.System.arraycopy (jpegObj.getComment().getBytes (), 0, cOM, 4,
    jpegObj.getComment().length ());
    WriteArray (cOM, out);

    // The dQT header
    // 0 is the luminance index and 1 is the chrominance index
    byte dQT[] = new byte[134];

    dQT[0] = (byte) 0xFF;
    dQT[1] = (byte) 0xDB;
    dQT[2] = (byte) 0x00;
    dQT[3] = (byte) 0x84;
    offset = 4;

    for (i = 0; i < 2; i++)
    {
    dQT[offset++] = (byte) ((0 << 4) + i);
    tempArray = dct.getQuantumArray (i);

    for (j = 0; j < 64; j++)
    {
    dQT[offset++] = (byte) tempArray[jpegNaturalOrder[j]];
    }
    }

    WriteArray (dQT, out);

    // Start of Frame Header
    byte startOfFrame[] = new byte[19];

    startOfFrame[0] = (byte) 0xFF;
    startOfFrame[1] = (byte) 0xC0;
    startOfFrame[2] = (byte) 0x00;
    startOfFrame[3] = (byte) 17;
    startOfFrame[4] = (byte) jpegObj.PRECISION;
    startOfFrame[5] = (byte) ((jpegObj.getImageHeight () >> 8) & 0xFF);
    startOfFrame[6] = (byte) ((jpegObj.getImageHeight ()) & 0xFF);
    startOfFrame[7] = (byte) ((jpegObj.getImageWidth () >> 8) & 0xFF);
    startOfFrame[8] = (byte) ((jpegObj.getImageWidth ()) & 0xFF);
    startOfFrame[9] = (byte) jpegObj.getNumberOfComponents ();
    index = 10;

    for (i = 0; i < startOfFrame[9]; i++)
    {
    startOfFrame[index++] = (byte) jpegObj.COMP_ID[i];
    startOfFrame[index++] = (byte) ((jpegObj.H_SAMP_FACTOR[i] << 4) + jpegObj.V_SAMP_FACTOR[i]);
    startOfFrame[index++] = (byte) jpegObj.Q_TABLE_NUMBER[i];
    }

    WriteArray (startOfFrame, out);

    // The dHT Header
    byte dHT1[], dHT2[], dHT3[], dHT4[];
    int bytes, temp, oldindex, intermediateindex;

    length = 2;
    index = 4;
    oldindex = 4;
    dHT1 = new byte[17];
    dHT4 = new byte[4];
    dHT4[0] = (byte) 0xFF;
    dHT4[1] = (byte) 0xC4;

    for (i = 0; i < 4; i++)
    {
    bytes = 0;
    dHT1[index++ - oldindex] = (byte) huf.getBits (i)[0];

    for (j = 1; j < 17; j++)
    {
    temp = huf.getBits (i)[j];
    dHT1[index++ - oldindex] = (byte) temp;
    bytes += temp;
    }

    intermediateindex = index;
    dHT2 = new byte[bytes];

    for (j = 0; j < bytes; j++)
    {
    dHT2[index++ - intermediateindex] = (byte) huf.getVal (i)[j];
    }

    dHT3 = new byte[index];

    java.lang.System.arraycopy (dHT4, 0, dHT3, 0, oldindex);
    java.lang.System.arraycopy (dHT1, 0, dHT3, oldindex, 17);
    java.lang.System.arraycopy (dHT2, 0, dHT3, oldindex + 17, bytes);

    dHT4 = dHT3;
    oldindex = index;
    }

    dHT4[2] = (byte) (((index - 2) >> 8) & 0xFF);
    dHT4[3] = (byte) ((index - 2) & 0xFF);

    WriteArray (dHT4, out);

    // Start of Scan Header
    byte SOS[] = new byte[14];

    SOS[0] = (byte) 0xFF;
    SOS[1] = (byte) 0xDA;
    SOS[2] = (byte) 0x00;
    SOS[3] = (byte) 12;
    SOS[4] = (byte) jpegObj.getNumberOfComponents ();
    index = 5;

    for (i = 0; i < SOS[4]; i++)
    {
    SOS[index++] = (byte) jpegObj.COMP_ID[i];
    SOS[index++] = (byte) ((jpegObj.D_C_TABLE_NUMBER[i] << 4) + jpegObj.A_C_TABLE_NUMBER[i]);
    }

    SOS[index++] = (byte) jpegObj.ss;
    SOS[index++] = (byte) jpegObj.se;
    SOS[index++] = (byte) ((jpegObj.ah << 4) + jpegObj.al);

    WriteArray (SOS, out);

    }

    private void WriteCompressedData (BufferedOutputStream outputStream)
    {
    float dctArray1[][] = new float[8][8];
    double dctArray2[][] = new double[8][8];
    int dctArray3[] = new int[8 * 8];

    int lastDCvalue[] = new int [jpegObj.getNumberOfComponents ()];
    int zeroArray[] = new int[64];  // initialized to hold all zeros

    int nothing = 0, not;
    int minBlockWidth, minBlockHeight;

    // This initial setting of minBlockWidth and minBlockHeight is done to
    // ensure they start with values larger than will actually be the case.
    minBlockWidth = ((jpegObj.getImageWidth () % 8 != 0)
    ? (int) (Math.floor ((double) jpegObj.getImageWidth () / 8.0) + 1) * 8 :

    jpegObj.getImageWidth ());
    minBlockHeight = ((jpegObj.getImageHeight () % 8 != 0)
    ? (int) (Math.floor ((double) jpegObj.getImageHeight () / 8.0) + 1) * 8 :

    jpegObj.getImageHeight ());

    for (int comp = 0; comp < jpegObj.getNumberOfComponents (); comp++)
    {
    minBlockWidth = Math.min (minBlockWidth, jpegObj.getBlockWidth (comp));
    minBlockHeight = Math.min (minBlockHeight, jpegObj.getBlockHeight (comp));
    }

    for (int r = 0; r < minBlockHeight; r++)
    {
    for (int c = 0; c < minBlockWidth; c++)
    {
    int xpos = c * 8;
    int ypos = r * 8;

    for (int comp = 0; comp < jpegObj.getNumberOfComponents (); comp++)
    {
    int blockWidth = jpegObj.getBlockWidth (comp);
    int blockHeight = jpegObj.getBlockHeight (comp);
    float[][] inputArray = (float[][]) jpegObj.getComponent (comp);

    for (int i = 0; i < jpegObj.V_SAMP_FACTOR[comp]; i++)
    {
    for (int j = 0; j < jpegObj.H_SAMP_FACTOR[comp]; j++)
    {
    int xblockoffset = j * 8;
    int yblockoffset = i * 8;

    for (int a = 0; a < 8; a++)
    {
    for (int b = 0; b < 8; b++)
    {

    // I believe this is where the dirty line at the bottom of the image is
    // coming from. I need to do a check here to make sure I'm not reading past
    // image data.
    // This seems to not be a big issue right now. (04/04/98)

    dctArray1[a][b] =
    inputArray[ypos + yblockoffset + a][xpos + xblockoffset + b];
    }
    }


    // results in poor right and bottom borders.
    if ((! jpegObj.isLastColumnDummy (comp) || c < blockWidth - 1)
    && (!jpegObj.isLastRowDummy (comp) || r < blockHeight - 1))
    {
    dctArray3 = dct.quantizeBlock (dctArray2, jpegObj.Q_TABLE_NUMBER[comp]);

    }
    else
    {
    zeroArray[0] = dctArray3[0];
    zeroArray[0] = lastDCvalue[comp];
    dctArray3 = zeroArray;
    }

    huf.encodeHuffmanBlock (outputStream, dctArray3, lastDCvalue[comp],
    jpegObj.D_C_TABLE_NUMBER[comp],
    jpegObj.A_C_TABLE_NUMBER[comp]);

    lastDCvalue[comp] = dctArray3[0];
    }
    }
    }
    }
    }

    huf.flushBuffer (outputStream);
    }

    private void WriteMarker (byte[] data, BufferedOutputStream out)
    {
    try
    {
    out.write (data, 0, 2);
    }
    catch (IOException e)
    {
    System.err.println ("Error: " + e.getMessage ());
    }
    }

    private void WriteArray (byte[] data, BufferedOutputStream out)
    {
    int i, length;

    try
    {
    length = (((int) (data[2] & 0xFF)) << 8) + (int) (data[3] & 0xFF) + 2;

    out.write (data, 0, length);
    }
    catch (IOException e)
    {
    System.out.println ("IO Error: " + e.getMessage ());
    }
    }


    /**
    619 * Main method
    620 *
    21  * @param args Command line arguments
    */
    public static void main (String args[])
    {
    String string = new String ();
    int defaultQuality = 80;

    // Check to see if the input file name has one of the extensions:
    // .tif, .gif, .jpg
    // If not, print the standard use info.
    if (args.length < 2)
    {
    StandardUsage ();
    }

    if (!args[0].endsWith (".jpg") &&!args[0].endsWith (".tif") &&!args[0].endsWith (".gif"))
    {
    StandardUsage ();

    // First check to see if there is an OutputFile argument. If there isn't
    // then name the file "InputFile".jpg
    // Second check to see if the .jpg extension is on the OutputFile argument.
    // If there isn't one, add it.
    // Need to check for the existence of the output file. If it exists already,
    // rename the file with a # after the file name, then the .jpg extension.
    }

    if (args.length < 3)
    {
    string = args[0].substring (0, args[0].lastIndexOf (".")) + ".jpg";
    }
    else
    {
    string = args[2];

    if (string.endsWith (".tif") || string.endsWith (".gif"))
    {
    string = string.substring (0, string.lastIndexOf ("."));
    }

    if (!string.endsWith (".jpg"))
    {
    string = string.concat (".jpg");
    }
    }

    File outFile = new File (string);

    for (int i = 0; outFile.exists (); i++)
    {
    outFile = new File (string.substring (0, string.lastIndexOf (".")) + i + ".jpg");

    if (i > 100)
    {
    System.exit (0);
    }
    }

    File inFile = new File (args[0]);

    try
    {
    if (inFile.exists ())
    {
    int qual = defaultQuality;
    FileOutputStream dataOut = null;

    try
    {
    dataOut = new FileOutputStream (outFile);
    }
    catch (IOException e)
    {
    }

    try
    {
    qual = Integer.parseInt (args[1]);
    }
    catch (NumberFormatException e)
    {
    StandardUsage ();
    }

    Image image = Toolkit.getDefaultToolkit ().getImage (args[0]);
    Encoder jpgEncoder = new Encoder (qual, dataOut);
    jpgEncoder.encodeJPEG (image);

    try
    {
    dataOut.close ();
    }
    catch (IOException e)
    {
    }
    }
    else
    {
    System.out.println ("I couldn't find " + args[0] + ". Is it in another directory?");
    }
    }
    catch (JPEGException e)
    {
    e.printStackTrace ();
    }
    finally
    {
    System.exit (0);
    }
    }

    /**
    * Standard usage method.
    */
    public static void StandardUsage()
    {
    System.out.println("Program usage: java Jpeg \"InputImage\".\"ext\" Quality [\"OutputFile\"[.jpg]]");
    System.exit(0);
    }
    }
     
Загрузка...
Похожие Темы - Сжатие Цветных Изображений
  1. antares
    Ответов:
    0
    Просмотров:
    302
  2. iivvnn
    Ответов:
    3
    Просмотров:
    3.247

Поделиться этой страницей