トップ 最新 追記

yoggy's diary

〜せかいのすみっこから〜


2008-12-06

RMagickを使ってRubyで画像ファイルを操作する

問題のファイルはこちら

#!/usr/bin/ruby
#
# CTF勉強会で出題されたforensic300を解くプログラム
# 2008/12/6
#
# RMagickはgemsとかでいれてください
#
#  $ sudo gem install rmagick
#
# 参考:
#   RMagick 1.15.0 User's Guide and Reference
#   http://www.simplesystems.org/RMagick/doc/
#
require 'rubygems'
require 'rmagick'

def usage
   STDERR.puts "usage : #{__FILE__} image_file"
   exit 0
end

usage if ARGV.size == 0

img = Magick::ImageList.new(ARGV[0])

pixels = img.get_pixels(0, 0, 6, 1)
pixels.each {|p|
  #RMagickでは0〜65535で表現されるみたいなので
  #0〜255の間に変換している
  r = p.red     >> 8
  g = p.green   >> 8
  b = p.blue    >> 8
  a = p.opacity >> 8

  # for test...
  #puts "ARGB: #{a} #{r} #{g} #{b}"
  #puts "    : #{[255-a,r,g,b].pack("C*")}"

  print [255-a,r,g,b].pack("C*")
}
puts

2008-12-07

OpenCVを使って動画ファイルから1フレームだけ画像を取り出す

CTF勉強会の時にちょっとだけ作ってみたプログラムです。

//
//  gcc -I/usr/local/include/opencv -L/usr/local/lib -lhighgui -lcv -lcxcore -o f400 f400.c
//
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#if _WIN32
  #pragma comment(lib, "cv.lib")
  #pragma comment(lib, "cxcore.lib")
  #pragma comment(lib, "highgui.lib")
#endif

int
main (int argc, char **argv)
{
  CvCapture *cap;
  IplImage  *img;

  // 動画ファイルをオープン
  cap = cvCaptureFromFile("f400.mpg");

  // 1フレームをキャプチャ
  img = cvQueryFrame (cap);

  // キャプチャしたイメージを保存
  cvSaveImage ("f400.png", img);

  cvReleaseImage (&img);

  return 0;
}

Mac OS Xで動作確認していますが、たぶんVisualC++でも使えると思います(未確認)

OpenCVの動画ファイルの取り扱いはDirectShowとかQuickTimeのコーデックが使われるはずです。 詳しくはhighguiの中身を見てくださいw


2008-12-08

PythonでPILを使ってみるテスト

Pythonの練習とCTF勉強会のforensic510を考えるために作ったプログラムです。 作りかけ途中なのですが、とりあえずここにメモ。

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# CTF勉強会で出題されたforensic510を回答するプログラム(書きかけ途中)
#
# 実行前にあらかじめPILをインストールしておいてください。
#
#   Python Imaging Library (PIL)
#   http://www.pythonware.com/products/pil/
#

import sys, os
import PIL.Image
import PIL.ImageDraw

if len(sys.argv) == 1:
  print "usage: " + __file__ + " image_file\n"
  sys.exit()

# 画像のロード
img = PIL.Image.open(sys.argv[1])
d = PIL.ImageDraw.Draw(img)

w = img.size[0]
h = img.size[1]

# RGBAのAのあるところは削除
for y in range(0, h):
  for x in range(0, w):
    c = img.getpixel((x,y))
    if c[3] == 0:
      c = (c[0], c[1], c[2], 255)
    else:
      c = (0, 0, 0, 0)
    d.point((x,y), c)
img.save("process1.png")

# 頻度解析
# key:色,value:カウント
hist = {}
for y in range(0, h):
  for x in range(0, w):
    color = img.getpixel((x,y))
    hist[color] = (hist[color] + 1) if hist.has_key(color) else 1

# (0,0,0,0)の色は抜いておく
del hist[(0,0,0,0)]

# key:カウント,value:色の配列
r_hist = {}
for color, count in hist.iteritems():
  if r_hist.has_key(count):
    r_hist[count].append(color)
  else:
    r_hist[count] = [color]

#count_keys = r_hist.keys()
#count_keys.sort()
#for count in count_keys:
#  print count, r_hist[count]

max_count = max(r_hist.keys())
max_color = r_hist[max_count][0]
print "一番多い色: 数:%d, 色:%s" % (max_count, r_hist[max_count])

# 一番多い色の点のx,y座標を取得
pos = []
for y in range(0, h):
  for x in range(0, w):
    color = img.getpixel((x,y))
    if color == max_color:
      pos.append((x,y))

print pos

for p in pos:
  x = p[0]
  y = p[1]
  print "(x,y) = (%03d, %03d) x+y=%d x-y=%d y-x=%d " % (x, y, x+y, x-y, y-x)

# 一番多い色の点を強調して表示する
for y in range(0, h):
  for x in range(0, w):
    c = img.getpixel((x,y))
    if c == max_color:
      c = (255, 0, 0, 255)
    else:
      # 該当しないところは少し明るさをおさえて表示
      c = (c[0]/10, c[1]/10, c[2]/10, 255)
    d.point((x,y), c)
img.save("process2.png")

PILはなかなかいい感じに使えるライブラリだけど、 個人的にPythonに慣れてないので、関数とかクラスの 使い方を調べている時間の方が長かったり(汗

Pythonを書くのに参考にしたサイトはこのあたりです。


2008-12-11

Base64のエンコード・デコード

それnkfでできるよ。ということでメモ。

エンコード
$ echo -n "hello world" | nkf -MB
aGVsbG8gd29ybGQ=

デコード
$ echo -n aGVsbG8gd29ybGQ= | nkf -mB
hello world

Base64についての詳細についてはWikipediaあたりを参照。

元データのサイズがちょうど3の倍数のときは文字列の終端に=がつかないのですが、 予選問題のときは分かりやすく==がついていることを期待しておきますw

本日のツッコミ(全3件) [ツッコミを入れる]

xcorp [/usr/bin/base64 ってのがあるよね]

yoggy [おお、それは知らんかった(;´Д`)]

TIP [JS使ってatob()でやってます。]


トップ 最新 追記

2003|01|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|
2010|01|02|03|