動かざることバグの如し

近づきたいよ 君の理想に

PHPのImageMagickでsetCompressionQualityが効かない件

結論

setCompressionQuality ではなく setImageCompressionQuality を使え

経緯

以下のようなPHPのコードでImageMagickで画像を圧縮しようとした。しかし一向に画像サイズが小さくならない。

<?php
$im = new Imagick('test.jpg');
$im-> setCompressionQuality(10);
$im->writeImage('test_1.jpg'); 

おかしいなあ

原因

ドキュメントにちゃんと書いてある

このメソッドは、たとえば Imagick::newPseudoImage などで作った新しい画像に対してだけ使えるものです。
既存の画像に対しては Imagick::setImageCompressionQuality() を使う必要があります。

つまり今回みたいに既存の画像を読み込んで圧縮する場合は setImageCompressionQuality() でないと意味がない

以下だと動く

<?php
$im = new Imagick('test.jpg');
$im->setImageCompressionQuality(10);
$im->writeImage('test_1.jpg'); 

このことは PHP: Imagick::setCompressionQuality - Manual でちゃーんと書いてある。ドキュメントは読もう!、終わり

参考リンク

PHP DockerにImageMagickをインストールする

環境

  • docker
  • php 7 多分5系でも可能

やりたいこと

公式のphp dockerイメージPHPImageMagickで画像処理を使いたい。

やり方

そのままでは無いので自分でImageMagickを追加する必要がある。がpeclでインストールしてdocker-php-ext-enable imagick するだけなので割と簡単

Dockerfileから継承する形でImageMagickを追加していく。

FROM php:7.4-alpine

RUN apk add --no-cache imagemagick \
&& apk add --no-cache --virtual .phpize-deps imagemagick-dev build-base autoconf libpng-dev libjpeg-turbo-dev libxml2-dev \
&& pecl install imagick \
&& docker-php-ext-enable imagick \
&& apk del .phpize-deps

imagemagickパッケージだけは実行時にも必要なので残しておく必要がある。

確認コード

正常にインストールできていれば以下のようなコードが動くはず

<?php
$im = new Imagick('test.jpg');
$im->writeImage('test.png'); 

対応フォーマット確認

docker run --rm imagick_php php -r 'print_r(Imagick::queryFormats());'

参考リンク

RubyのMechanizeでフォームなしでPOST送信

環境

やりたいこと

Mechanizeでフォーム送信はできるが、普通はすでにページに存在するフォームに対してsubmitするのが一般的

ここではあえてコードだけでデータを付けた状態でフォーム送信をしてみる

コード

agent = Mechanize.new

url = "https://httpbin.org/post"
params = {
  "foo" => "bar"
}

node = {}
# Create a fake form
class << node
  def search(*args); []; end
end
node["method"] = "POST"
node["enctype"] = "multipart/form-data"
form = Mechanize::Form.new(node)
Mechanize::Util.each_parameter(params) do |k, v|
  form.fields << Mechanize::Form::Field.new({"name" => k.to_s}, v)
end
form.action = url
agent.submit(form)

これで multipart/form-data で送信できる。けどこれだったら普通にRestClient使ったほうがいいね

vuejsでコンポーネントをボタンで切り替え

pages/debug.vue

<template>
  <div id="app">
    <button @click="setView('1')" v-bind:class="{active: currentView == 'page1'}">
      1
    </button>
    <button @click="setView('2')" v-bind:class="{active: currentView == 'page2'}">
      2
    </button>
    <myComponent :is="currentView" />
  </div>
</template>

<script>
import page1 from '~/components/page1.vue'
import page2 from '~/components/page2.vue'

export default {
  components: {
    page1,
    page2
  },
  data () {
    return {
      currentView: 'page1'
    }
  },
  methods: {
    setView (val) {
      this.currentView = 'page' + val
    }
  }
}
</script>

<style scoped>
.active {
  background: red;
}
</style>

components/page1.vue

<template>
  <p>page1</p>
</template>

components/page2.vue

<template>
  <p>page2</p>
</template>

何故かNo space left on deviceでApacheが起動できない時の対処法

  • No space left on device: Cannot create SSLMutex
  • No space left on device: Couldn't create accept lock
  • No space left on device: mod_rewrite: could not create rewrite_log_lock

Apacheが起動できない状態で、解放されず残っているapacheユーザのセマフォを消すには、rootユーザで

ipcs -s | awk '/apache/{print $2}' | xargs -r ipcrm sem
(/apache/のところは、Apache実行ユーザに読み替えよう)