質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.61%

  • Ruby

    7325questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    6985questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

  • ImageMagick

    92questions

    ImageMagickとは、画像の表示や操作を行うオープンソースのソフトウェアです。プログラムはCで書かれており、GIFやJPEG、PDFなど画像ファイルフォーマット100種類以上に対応しています。

モデルから取得した変数を、public配下のrbファイルに渡したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 134

naoya.n

score 11

RailsとRMagickを使って画像にテキストを加工するアプリケーションを作っています。
publicに置いたtest2.pngという画像にコントローラからrmagick.rbを実行するものを作りました。song.rb, translation.rb, lyric.rbというモデルから取得したデータをSongsControllerというコントローラからpublic配下のrmagickに、変数を渡したいです。
グローバル変数を作って見たのですが、rmagickでうまく取得できません。
どうすればpublic/rmagick.rbで、モデルのデータをSongsControllerを介して取得できるでしょうか。

現状、直で書いた文字列だとうまく動くところまでは確認してます。

public/rmagick.rb

require 'fileutils'
require 'RMagick'

# メッセージ
MSG_USAGE     = "USAGE: ruby rmagick.rb filename"
MSG_NOT_EXIST = "File not exist!"

class Arg
  # 引数取得
  def get_arg
    begin
      if ARGV[0]
        # ファイルが存在しなければ終了
        unless File.exist?(ARGV[0])
          puts MSG_NOT_EXIST + " #{ARGV[0]}"
          exit
        end
      else
        # 引数無ければ終了
        puts MSG_USAGE
        exit
      end

      # ファイル名返却
      return ARGV[0]
    rescue => e
      STDERR.puts "[ERROR][#{self.class.name}.get_arg] #{e}"
      exit 1
    end
  end
end

class Rmagick

  def initialize(filename)
    @img_file = filename
  end

  # テキスト描画
  def rmagick(columns = 5)
    FileUtils.cp(@img_file, "2"+@img_file, {:preserve => true})  # 元画像退避
    img  = Magick::ImageList.new(@img_file)  # 画像オブジェクト
    draw = Magick::Draw.new                  # 描画オブジェクト


   #ここで変数を受け取りたい!!!!
    str = $translation_img
    str2 = $lyric_img
    str3 = $title_img

    begin
#ここに変数を代入したい!!!!!!
      draw.annotate(img, 0, 0, 70, 320, str3.scan(/.{1,#{30}}/).join("\n")) do

        self.fill      = 'white'
        self.stroke    = 'transparent'
        self.pointsize = 24
        self.gravity   = Magick::NorthWestGravity
      end

      draw.annotate(img, 0, 0, 70, 165, str2.scan(/.{0,44}[a-z.!?,;](?:\b|$)/mi).join("\n") ) do
        self.fill      = 'white'
        self.stroke    = 'transparent'
        self.pointsize = 44
        self.gravity   = Magick::NorthWestGravity
      end

      draw.annotate(img, 0, 0, 68, 55, str) do

        self.fill      = 'white'
        self.stroke    = 'transparent'
        self.pointsize = 24
        self.gravity   = Magick::NorthWestGravity
      end

      # 画像生成
      img.write("2"+@img_file)
    rescue => e
      STDERR.puts "[ERROR][#{self.class.name}.rmagick] #{e}"
      exit 1
    end
  end
end

# 引数取得
obj_arg = Arg.new
filename = obj_arg.get_arg

# Copyright 描画
obj_main = Rmagick.new(filename)
obj_main.rmagick


SongsController.rb

  def share

    @translation= Translation.find_by(id: params[:id])
    @lyric = Lyric.find_by(number: @translation.number , song_id:@translation.song_id)
    @song = Song.find_by(id: @translation.song_id)
   #インスタンス変数をモデルから取得

  #これをグローバル変数にしてrmagick.rbに渡したい
    $translation_img = @translation.content
    $lyric_img = @lyric.content
    $artist_img = @song.artist
    $title_img = @song.title

    if @current_user
      @user = User.find_by(id: @current_user.id)
    end
  #public/rmagickに引数を与えて実行
    system("cd ~/lyrica/public/tweet_img && pwd && ruby rmagick.rb test2.png")
  end

追記

### lib / rmagick.rb

require 'fileutils'
require 'RMagick'


class Arg
  # 引数取得
  def get_arg
    begin
      if ARGV[0]
        # ファイルが存在しなければ終了
        unless File.exist?(ARGV[0])
          puts MSG_NOT_EXIST + " #{ARGV[0]}"
          exit
        end
      else
        # 引数無ければ終了
        puts MSG_USAGE
        exit
      end

      # ファイル名返却
      return ARGV[0]
    rescue => e
      STDERR.puts "[ERROR][#{self.class.name}.get_arg] #{e}"
      exit 1
    end
  end
end

class Rmagick
  attr_reader :translation, :lyric, :title, :artist

  def initialize(filename, translation_img:, lyric_img:, title_img:, artist_img:)
    @filename = filename
    @translation = translation_img
    @lyric = lyric_img
    @title = title_img
    @artist = artist_img
  end

  # テキスト描画
  def rmagick(columns = 5)

    FileUtils.cp(@filename, "2"+@filename, {:preserve => true})  # 元画像退避
    img  = Magick::ImageList.new(@filename)  # 画像オブジェクト
    draw = Magick::Draw.new                  # 描画オブジェクト
    begin
      draw.annotate(img, 0, 0, 70, 320, @lyric.scan(/.{1,#{30}}/).join("\n")) do

        self.fill      = 'white'                 
        self.stroke    = 'transparent'         
        self.pointsize = 24                    
        self.gravity   = Magick::NorthWestGravity 
      end

      draw.annotate(img, 0, 0, 70, 165, @tranalation.scan(/.{0,44}[a-z.!?,;](?:\b|$)/mi).join("\n") ) do

        self.fill      = 'white'                 
        self.stroke    = 'transparent'      
        self.pointsize = 44               
        self.gravity   = Magick::NorthWestGravity
      end

      draw.annotate(img, 0, 0, 68, 55, @title) do

        self.fill      = 'white'             
        self.stroke    = 'transparent'    
        self.pointsize = 24 
        self.gravity   = Magick::NorthWestGravity
      end

      # 画像生成
      img.write("2"+@filename)
    rescue => e
      STDERR.puts "[ERROR][#{self.class.name}.rmagick] #{e}"
      exit 1
    end
  end
end


### SongsController.rb

def share

    @translation= Translation.find_by(id: params[:id])
    @lyric = Lyric.find_by(number: @translation.number , song_id:@translation.song_id)
    @song = Song.find_by(id: @translation.song_id)

    if @current_user
      @user = User.find_by(id: @current_user.id)
    end

        images = {
      translation_img: @translation.content,
      lyric_img: @lyric.content,
      artist_img: @song.artist,
      title_img: @song.title
      }
      filename = Rails.root.join('public', 'test2.png')
      ::Rmagick.new(filename.to_s, **images).rmagick if filename.exist?
  end
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

public配下にrbファイルを置くのは斬新ですね・・基本的にpublic配下には静的ファイル置くのがいいんじゃないでしょうか、承知の上かもしれませんが。

うまくいかない原因はsystemで実行しているためrbagick.rbRailsと別プロセスになっているのが原因だと思います。

publicではなくて例えばlib配下にrmagick.rbを置いて以下のように修正してみてはどうでしょうか? 

# lib/rmagick.rb
class Rmagick
  # str1などの変数はわかりにくいのでそのまま`translation`などがいいと思います。
  attr_reader :translation, :lyric, :title, :artist

  def initialize(filename, translation_img:, lyric_img:, title_img:, artist_img:)
    @filename = filename
    @translation = translation_img
    @lyric = lyric_img
    @title = title_img
    @artist = artist_img
  end

 # ..省略
end

class SongsController < ApplicationController
  def share
    # ...略
    images = {
      translation_img: @translation.content,
      lyric_img: @lyric.content,
      artist_img: @song.artist,
      title_img: @song.title
    }
    filename = Rails.root.join('public', 'test2.png')
    ::Rmagick.new(filename.to_s, **images).rmagick if filename.exists?
  end
end

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/03 15:05

    NameError in SongsController#share
    uninitialized constant Rmagick
    になってしまいます、、!!
    どうすればいいかわかりますでしょうか、、m(__)m!!
    rmagick.rbはlib配下、test2.pngはpublic配下におきました。
    編集後のコードは追記しました!!!

    キャンセル

  • 2018/06/03 15:25 編集

    あーすみません、lib配下がautoload_pathに追加されている前提で書いてしまっていました。

    config/application.rbに以下の行を追記すれば動くと思います。

    config.autoload_paths += %W(#{config.root}/lib)

    キャンセル

  • 2018/06/03 16:42

    うまくいきました!!ありがとうございます!!!!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    引数の渡し方が間違っているのでしょうか?

    rubyでじゃんけんプログラムを作っているのですが、勝率・敗率等を出そうとしてもうまく動きません。 条件として、 ・Rubyファイル、入力ファイル、出力ファイルの3つを用意

  • 解決済

    ファイル内文字列検索し、特定の文字列が含まれたファイル名、ファイルパスを取得したい

    ある特定のディレクトリ配下にあるファイル内から特定の文字列が含まれているファイルを検索し、そのファイル名とファイルパスをrubyプログラムで取得いたいのですがどのようにしたら良いか

  • 受付中

    実装方法、検索アルゴリズムの改善

    課題 下記の課題を出題されました。 機能としては実装できましたが、よりよいアルゴリズム、実装方法があるのでは?と考えております。 アドバイスを頂きたく投稿致しました。 下記

  • 受付中

    コマンドプロンプトで計算ゲームをしたいが、正解率の所でエラーになる件

    ご覧いただきありがとうございます。 現在、コマンドプロンプト(ターミナル)で計算ゲームをするプログラムを作っています(おもに練習用です) まだrubyの勉強初めて一週間

  • 受付中

    Ruby : メソッド定義について

    テキスト処理についてのコードです。 Rubyでテキスト処理をしているのですが、同じような繰り返しが2回あるので、なんとかメソッドにして綺麗にコードを書けないかなと思って、試して

  • 受付中

    php shell_exec()でrubyに渡す

    phpからrubyにsehll_execを使って変数を渡したいと思います。 $results = shell_exec("ruby s3delete.rb devtouch2

  • 解決済

    Ruby 配列間でのvalueの計算

     前提・実現したいこと ゲームに参加するにはメダルが必要です。 必要メダルと所持メダルの配列があります。 keyはメダルの種類。valueはその数です。 足りていない場合はエラ

  • 解決済

    Ruby while until 分からないです(泣)

    今年の春から大学一年生です。 学校の課題で「Ruby」でwhile文とuntil文の課題が出されました。 ・while文による繰り返し制御を使って、コインを10回投げ、その「表

同じタグがついた質問を見る

  • Ruby

    7325questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    6985questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

  • ImageMagick

    92questions

    ImageMagickとは、画像の表示や操作を行うオープンソースのソフトウェアです。プログラムはCで書かれており、GIFやJPEG、PDFなど画像ファイルフォーマット100種類以上に対応しています。