theonlineoasis

Code samples on this website come without any guarantees – use them at your own risk! I am grateful for comments or patches sent to my email address: first name.last name@cl.cam.ac.uk.

#!/usr/bin/python

from PIL import Image, ImageOps

import math
import matplotlib.pyplot
import numpy
import os
import sys

#from accel.dct_accel import dct
from pylibjpeg.libjpeg import libjpeg

if len(sys.argv) != 4:
  print "Usage:\n\t%s original.ppm quality_1 quality_2" % (sys.argv[0],)
  sys.exit(0)

source_file_name = sys.argv[1]
quality_1 = int(sys.argv[2])
quality_2 = int(sys.argv[3])
final_file_name = '%s.%d.%d.jpg' % (source_file_name, quality_1, quality_2,)

os.system('cjpeg -outfile %s.%d.jpg -quality %d %s' % (source_file_name, quality_1, quality_1, source_file_name,))
os.system('djpeg -outfile %s.%d.ppm %s.%d.jpg' % (source_file_name, quality_1, source_file_name, quality_1,))
os.system('cjpeg -outfile %s -quality %d %s.%d.ppm' % (final_file_name, quality_2, source_file_name, quality_1,))
#os.system('djpeg -outfile %s.%d.%d.ppm %s.%d.%d.jpg' % (source_file_name, quality_1, quality_2, source_file_name, quality_1, quality_2,))
os.system('rm %s.%d.jpg %s.%d.ppm' % (source_file_name, quality_1, source_file_name, quality_1))

DCT_SIZE = 8
FREQUENCY = (2, 1)

(qmatrices, blocks) = libjpeg().get_jpeg_info(final_file_name)
qy = qmatrices[0]
blocks_y = blocks[0]
frequency_values = [b[FREQUENCY[0] + FREQUENCY[1] * DCT_SIZE] for b in blocks_y]
furthest_value = max(abs(min(frequency_values)), abs(max(frequency_values)))
bin_count = furthest_value * 2 + 1
n, bins, patches = matplotlib.pyplot.hist(frequency_values, bin_count, (-furthest_value, furthest_value))
matplotlib.pyplot.show()

sys.exit(0)

# Approximate DCT code:

# Convert the image to greyscale.
image = Image.open(final_file_name)
greyscale = ImageOps.grayscale(image)
greyscale_matrix = numpy.reshape(numpy.fromstring(greyscale.tostring(), dtype=numpy.uint8).astype(float), (greyscale.size[1], greyscale.size[0]))

cos_table = numpy.zeros((DCT_SIZE, DCT_SIZE), dtype=float)
for i in range(0, DCT_SIZE):
  for j in range(0, DCT_SIZE):
    cos_table[i, j] = math.cos((2 * i + 1) * j * math.pi / (2 * DCT_SIZE))

# DCT each DCT_SIZE * DCT_SIZE block of samples.
coefficient_values = []
for ty in range(0, greyscale.size[0] / DCT_SIZE):
  for tx in range(0, greyscale.size[1] / DCT_SIZE):
    tile = greyscale_matrix[tx * DCT_SIZE : tx * DCT_SIZE + DCT_SIZE, ty * DCT_SIZE : ty * DCT_SIZE + DCT_SIZE]
    print numpy.round(dct(tile, cos_table))
    raw_input()
    coeff_value = round(dct(tile, cos_table)[FREQUENCY])
    if coeff_value >= HIST_MIN and coeff_value <= HIST_MAX:
      coefficient_values.append(coeff_value)
n, bins, patches = matplotlib.pyplot.hist(coefficient_values, 50)
matplotlib.pyplot.show()