Archive for the ‘Programming’ Category

python-logo-master-v3-TM

先日Linux上でPythonのプログラムを開発していた時にディレクトリの中の画像ファイル一覧を取得したいなあと思う事がありました。

ディレクトリの中にはテキストファイルや、csvファイルが同時に含まれていたのですが、画像ファイルの一覧だけをリスト化したいなあと。

という事でどうやって解決したのかをここに記して置こうと思います。

import commands
jpgList = []
jpgList =  commands.getoutput("ls targetPath | grep *.jpg").split("\n")

osモジュールのlistdir()メソッドとかでもディレクトリとファイルの参照が出来るようですが、使い慣れたbashの出力をそのままゲット出来るcommands.getoutput()メソッドの方が便利だなと私は感じました。

このメソッドに文字列を渡すとカレントディレクトリでシェルコマンドを実行、返り値を取得する事ができます。

次のsplit()メソッドがキモなのですが、lsの返り値は"\n"で区切られています。

適当なファイルのあるディレクトリ内で

ls > result.txt
less result.txt

とやってみれば改行がIFS(内部フィールド区切り文字 (Internal Field Separator))となっている事が分かると思います。

よって、split("\n")で改行によって分割、リスト化してあげればlsの返り値を簡単にリスト化する事が出来るというワケです。

読者諸兄におかれましては蛇足となりましょうが、 "| grep *.jpg" によってファイル末尾(拡張子)が".jpg"のファイル群のみをリストアップするようにする事でjpgファイルらのみをリスト化しております。

python-logo-master-v3-TM

Pythonでは文字列型に文字を挿入するメソッドが存在しないようですね。
リスト型に挿入する方法はあるのですが・・・。

まあここらへんは各々ハックされていらっしゃる事だと存じますが、
今回私が使った手法をご紹介させていただこうとおもいます。

例えば 
"http://www.example.jp/0/1/700/500.1.jpg"という文字列があったとして
文字列中の"/1/"の部分を"/7/"に変更したいとします。
これだけなら.replace()メソッドを使う事で実現できてしまうのですが、もしも文字列が
"http://www.example.jp/1/1/700/500.1.jpg"
であった場合、"/1/"は2つ存在する事になり、両方とも置換されてしまいます。
この様な動作が目的に沿わない場合もある事でしょう。

こういうケースの場合以下の様に書く事によって、任意の場所の文字列を変更する事が可能です。

src = "http://www.example.jp/0/1/700/500.1.jpg"

#文字列の末尾から"/1/"を検索、その場所を確保
idx = src.rfind(r'/1/')

#ここがキモです。pythonでは文字列は非破壊なので、新しい変数を用意する必要があります。
#スライスを使って文字列srcのidxまでの文字列を取得、そこに"/7/"を加えて、更にスライスを用いてidx+3(+3は"/7/"の3文字を表す)より後の文字列を結合させています。
result = src[:idx] + "/7/" + src[idx+3:]

以上の方法によって私は、文字列の挿入を可能としました。

文字列の「スライス」の方法は以下に詳しく書いてあります。
スライスを使った部分文字列の取得

jQuery_logo

マウスオーバーで画像を切替える方法はいくつかあります。
大別してCSSを使ってやる方法とJavascriptを使ってやるというのが主流かと思います。

CSSでやる場合、ボタンの切り替えはどうしても瞬間的に切り替わるものになってしまいます。
(ふわっと切り替える方法もあるのかな・・・)

でもやっぱり僕的には「ふわり」と切り替わるエフェクトの方が好みなんです。
そこで今回はJavascriptを使ってやる方法を選択してみました。

Javascriptを使って簡単にアニメーションを実装といえばもちろんjQueryさんの出番です。

と言う事で、HTMLのHEAD内にまずはjQueryをインポートしてしまいましょう。

<head>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
	<script type="text/javascript" src="./scripts/smart-crossfade.js"></script>
</head>

2行目googleのライブラリからjQueryを引っ張ってきてインポート。
3行目でインポートしてる"smart-crossfade.js"が今回の肝にあたるライブラリです。

こいつを使うとどうなるのか。

こちらにサンプルを用意しました。
smart-crossfade demo

このとおりふわりと画像が切り替わるのですね!

使用するには色違いの画像を2枚用意して、それぞれのファイル名の末尾を"_on","_off"としてあげます。
"button_off.jpg","button_on.jpg"といった具合にですね。

_offをつけている方はマウスが画像から外れている時に表示する画像。
_onをつけている方がマウスオーバーした時に表示する画像となっています。

後はその画像をaタグで囲ってあげると自動的に、ふわっと画像が切り替わるマウスオーバーエフェクトが実装されています。

以下実装ソースです。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>smart-crossfade demo</title>
<script src="js/jquery-1.11.3.min.js"></script>
<script src="js/smart-crossfade.js"></script>
</head>
<body>
<a href="#"><img src="img/facebook_off.png"></a>
<a href="#"><img src="img/twitter_off.png"></a>
<a href="#"><img src="img/google_off.png"></a>
<a href="#"><img src="img/rss_off.png"></a>
</body>
</html>

ライブラリのソースも一応アップしときます。

function smartRollover() {
	if(document.getElementsByTagName) {
		var images = document.getElementsByTagName("img");

		for(var i=0; i < images.length; i++) {
			if(images[i].getAttribute("src").match("_off."))
			{
				images[i].onmouseover = function() {
					this.setAttribute("src", this.getAttribute("src").replace("_off.", "_on."));
				}
				images[i].onmouseout = function() {
					this.setAttribute("src", this.getAttribute("src").replace("_on.", "_off."));
				}
			}
		}
	}
}

if(window.addEventListener) {
	window.addEventListener("load", smartRollover, false);
}
else if(window.attachEvent) {
	window.attachEvent("onload", smartRollover);
}


// cross fade

new function(){
  function setRollOver2(){
    if(!document.images){return;}
    var imgs = document.images;
    var insert = [];
    for(var i=0;i<imgs.length;i++){
      var splitname = imgs[i].src.split('_off.');
      if((splitname[1])&&(imgs[i].parentNode.tagName=='A')){
        var rolloverImg = document.createElement('img');
        rolloverImg.src = splitname[0]+'_on.'+splitname[1];
        var alpha = 0;
        rolloverImg.currentAlpha = alpha;
        rolloverImg.style.opacity = alpha/100;
        rolloverImg.style.filter = 'alpha(opacity='+alpha+')';
        rolloverImg.style.position = 'absolute';


        addEvent(rolloverImg,'mouseover',function(){setFader(this,100);});
        addEvent(rolloverImg,'mouseout',function(){setFader(this,0);});

        insert[insert.length] = {position:imgs[i],element:rolloverImg};
      }
    }
    for(var i=0;i<insert.length;i++){
      var parent = insert[i].position.parentNode;
      parent.insertBefore(insert[i].element,insert[i].position);
    }
  }


  function setFader(targetObj,targetAlpha){
    targetObj.targetAlpha = targetAlpha;
    if(targetObj.currentAlpha==undefined){
      targetObj.currentAlpha = 100;
    }
    if(targetObj.currentAlpha==targetObj.targetAlpha){
      return;
    }
    if(!targetObj.fading){
      if(!targetObj.fader){
        targetObj.fader = fader;
      }
      targetObj.fading = true;
      targetObj.fader();
    }
  }

  function fader(){
    this.currentAlpha += (this.targetAlpha - this.currentAlpha)*0.2;
    if(Math.abs(this.currentAlpha-this.targetAlpha)<1){
      this.currentAlpha = this.targetAlpha;
      this.fading = false;
    }
    var alpha = parseInt(this.currentAlpha);
    this.style.opacity = alpha/100;
    this.style.filter = 'alpha(opacity='+alpha+')';
    if(this.fading){
      var scope = this;
      setTimeout(function(){fader.apply(scope)},30);
    }
  }

  function addEvent(eventTarget, eventName, func){
    if(eventTarget.addEventListener){
      eventTarget.addEventListener(eventName, func, false);
    }else if(window.attachEvent){
      // IE
      eventTarget.attachEvent('on'+eventName, function(){func.apply(eventTarget);});
    }
  }

  addEvent(window,'load',setRollOver2);

}

ちなみにフェードインのスピードは87行目
setTimeout(function(){fader.apply(scope)},30);
の30という数字をいじる事で変更する事が可能です。

と言う事で、僕の知る限り最も簡単なマウスオーバーでのハイクオリティな画像切替方法でした。