あなたのポケットの中のLinux-写真家のサービスで

写真が私の主な職業活動であり、プログラミングは趣味であることがたまたまありました。 脳のために直接ウォームアップすることに加えて、プログラミングは仕事に役立ちます。 たとえば、 thisthisthisなどの便利なものを書きました。



最近、私は顧客を喜ばせるかのように自分で仕事を設定しました。 結婚式の撮影に対するクライアントの多くのリクエストを思い出しました。「バンケットで日中に撮った写真の短いスライドショーを見せてくれたらどんなにいいだろう」 これらの要求は、いくつかの理由で拒否する必要がありました:ラップトップを持ち運んでスライドショーを作成するのが面倒で、数百から数十枚の写真を選択する時間がありません。



これは私が自分で楽器を作る方法についての物語であり、バックパックへの最小限の関与と最小限の重量で、美しいスライドショーを作るのに役立ちます。 そしてもちろん、アンドロイドでのpython、ffmpeg、およびlinuxについての話。



予想外の鉄の選択



最初の問題は太りすぎです。 十分なハードウェアでフルLinuxが必要でした。 当初、私の選択はgigtimeで聞いたOrange PI PC でした 。 鉄片が注文され、配達されました。 これが必要なものであるように思えました-1.5 GHzの4コア、1 GBのRAM、フルUSB。 しかし、実際には、通常のサポートがなければ、すべての「ラズベリークローン」は価値がないと改めて確信しました。 非常にバグの多いOSイメージ、負荷のかかったカーネルから絶えず落ちる、たとえばLCDディスプレイを接続するためのライブラリの問題。

そして主な問題は、次のようなコードの一部で、800 MBのRAMが空き、予期せずに終了することです

from PIL import Image img=Image.new('RGB',(6000,4000)) #      ,    img.rotate()
      
      





さらに、同じことが、スワップなしの1GBのRAMを搭載したネットブックでも、最初のRaspberry PIでも完全に機能しました。 さらに、同じことをすることは間違いありませんが、同時に4つのコアで実行できます。



来たメッセージを読むためにスマートフォンを手にしたとき、意外な決断が下されました。

また、ポケットには常に2.2 GHz 4コアプロセッサを備えた鉄片があり、2 GBのRAM + USB-otgが利用できます(Nexus 5)。 Linux環境を完全に起動する方法を見つけることは残っています。 点滅するさまざまなオプションを破棄した後(完全にスマートフォンとして使用したかった)、ソリューションが見つかりました-Linux Deploy 。 要するに、Linux Deployはchrootで本格的なlinux環境を起動します(同プログラムの詳細については、同胞の開発者-開発者)。私にとって最も重要なことは、fs Androidから任意のディレクトリを環境にマウントすることです。 これがないと、OTGコネクタに挿入されたSDカードリーダーで作業することができません。



写真の選択



数百枚の写真のスライドショーには数時間かかります。 20〜40枚の写真をすばやく簡単に選択する方法が必要でした。 スマートフォンから100枚の写真をスクロールするのも楽しみであり、その数は夕方までに最大1000枚に達することがあります(連続撮影、結婚、写真の確認、報告などからの重複)。

カメラを見たとき、私は使用したことがないボタンについて思い出しました-「評価」ボタンは、写真に評価を割り当てる救世主であることが判明しました:







右側のスクロールホイールで写真をすばやくスクロールし、目的のボタンをクリックして「レート」ボタンをクリックします。 今日成功しているすべてのものを撮影したことを既に知っているので、数分もかかりません。 プログラムに、少なくとも何らかの評価が割り当てられている画像を見つけて選択させることを強制します。



評価はexifに該当するため、素晴らしいexiftoolパッケージ(sudo apt-get install libimage-exiftool-perl)とPython用のラッパーが必要になります 。 そして、すべてが簡単です:



 import os import exiftool all_files=[] """     SD  """ for directory, dirnames, filenames in os.walk(PATH_TO_SD_ROOT): for name in filenames: f=os.path.join(directory, name) if f.lower().endswith('.cr2') or f.lower().endswith('.jpg'): #    jpg  raw  all_files.append(f) tool=exiftool.ExifTool() tool.start() # exiftool #         result=tool.get_tags_batch(['XMP:Rating'],all_files) rated_files=[] for x in result: if x['XMP:Rating']>0: rated_files.append(x['SourceFile']) #        rated_files.sort()
      
      







次の段階は非常に簡単です-必要な写真を一時ディレクトリにコピーし、さらに作業するために複数のスレッドに分割します。 私が焦点を当てたいのは、生の写真だけです。 dcrawユーティリティは変換に関与します(これは完全な変換ではありませんが、有線jpgをrawファイルにプルするだけですが、この場合はこれで十分です。



 import subprocess for n,x in enumerate(self.rated_files): dcraw_opts = ["dcraw", "-e", "-c", x] # -e -   jpg, -     stdout dcraw_proc = subprocess.Popen(dcraw_opts, stdout=subprocess.PIPE) image = StringIO.StringIO(dcraw_proc.communicate()[0]) #    stdout image.seek(0) open('input/%02d.jpg'%(n),'wb').write(image.read()) #     .
      
      







私を美しくしてください!





前の段階で、写真を撮って、プロジェクターに接続されたDJのラップトップでスライドショーのようにすることで停止できましたが、美しく見せたいです。

ffmpeg(avconv)のような素晴らしいものが助けになります。 私は明るい特殊効果のファンではありません。ズーム写真やスライド間の「クロスフェード」トランジションという形で十分な簡単なダイナミクスを持っています。 ffmpegの膨大な機能にもかかわらず、私はすぐにこれを行うことに成功しませんでした。 たとえば、ズームパンフィルターはひどい品質と震える画像を示しました。 マニュアルやフォーラムを読むのに一週間を費やした後、「額」にすることにしました。



 def processImage(numb): img=Image.open('input_temp/%02d.jpg'%numb) #    #   crossfade   ,    ,   try:next_img=Image.open('input_temp/%02d.jpg'%(numb+1)).resize((1280,720),Image.ANTIALIAS) except:next_img=Image.new('RGB',(1280,720),'black') #       ,  ffmpeg   stdin  #        p = subprocess.Popen(['avconv', '-y', '-f', 'image2pipe', '-vcodec', 'mjpeg', '-r', '25', '-i', '-', '-vcodec', 'mjpeg','-q:v', '3' , '-r', '25', 'output/%02d.mjpg'%(numb)], stdin=subprocess.PIPE) # 100   25 /c - 4     for x in xrange(100): #            16:9 n=img.crop((int(float(x)*16.0/9.0),x,int(1920.0-float(x)*16.0/9.0),1080-x)) #       n=n.resize((1280,720),Image.ANTIALIAS) #   ,  ""   if x>75: n=Image.blend(n,next_img,float(x-75)/25) #   ffmpeg' n.save(p.stdin,'JPEG') p.stdin.close() p.wait()
      
      







ああ、プロセッサコアについて何か言いました。 このプロセスを並列化して、すべてのコアが占有されるようにします。 Pythonでは、これは非常に単純に行われます。

 from multiprocessing import Pool s=len(glob.glob('input_temp/*.jpg')) #   pool = Pool() pool.map(processImage, xrange(s)) #    ,        pool.close() pool.join()
      
      







その結果、音楽を挿入して結合する必要があるmjpegビデオが多数あります。

グーグル、私は最初に猫を使用してビデオを直接接続するより良い方法を見つけませんでした:

 cat 00.mjpg 01.mjpg ..... > out.mjpg
      
      





音楽を追加して、目的の形式に変換するだけです。

 avconv -threads 4 -framerate 25 -i out.mjpg -i audio.mp3 -shortest -y -r 25 -preset veryfast out.mp4
      
      







コンソールで毎回わずらわされないようにするために、音楽トラックを選択し、スライドショーの名前を入力する必要があります(最初のフレーム用)など、Linux Deployの起動時に起動する単純なWebサーバーを作成しました。 単純なボトルフレームワークを使用しました。 次のようになります。







合計



写真の選択2〜3分、Linux Deployの起動、ブラウザーのローカルホスト、タイトルを入力して「開始」をクリックするために数秒。 その後、10〜15分のスマートフォン操作が完了し、ビデオの準備ができました。







同様に、写真のスライドショーだけでなく、ビデオを接着することもできます。カメラの必要な部分をレートボタンでマークし、ffmpegで接着します。



そして少しの発表


このトピックが興味深いことが判明した場合は、さらにいくつかの出版物を作成します。 たとえば、次の記事は、このようなキュートで機能的な写真ブースの作り方です。








All Articles