LoginSignup

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Canvasの画像保存とその利用を教えて欲しい!!!!

前提

AndroidStudioでKotlinを用いてルーレットの画像を作成し回転させるアプリを作っています。
回転に関してはある程度できたのですが、画像作成をした後の保存の部分がよくわかりません。
色々なことを調べてみてプログラム上ではエラーの表示はありませんが、仮想デバイス上でアプリを開いた時に”RouletteImage keeps stopping”(RouletteImageはアプリ名)というアラートダイアログが表示されアプリが開始されません。

実現したいこと

1,ルーレットの各項目の割合を所得しCanvasに円グラフのような画像を作成する
2,Canvas上の画像をアプリ内にPNGとして保存する
3,保存した画像を回転させる

現状2ができていないためその部分を質問しております。
そのため、1ができているか確認できていません。
3はサンプルの画像を回転させることができたので、ここは変えたいと考えておりません。

発生している問題・エラーメッセージ

仮想デバイスのアラートダイアログ上で以下のように通知されます。
スクリーンショット 2022-10-11 12.38.05.png

AndroidStudio側ではエラー文は表示されていません。

該当のソースコード

package com.example.rouletteimage

import android.content.Context
import android.content.Intent
import android.graphics.*
import android.graphics.Bitmap.CompressFormat
import android.os.Build
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.View
import android.widget.Button
import android.widget.EditText
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
import kotlin.properties.Delegates


class MainActivity : AppCompatActivity() {

    private var paint: Paint = TODO()
    private val paint1 = Paint()
    private val paint2 = Paint()
    private val paint3 = Paint()
    private val paint4 = Paint()
    private val paint5 = Paint()
    private val paint6 = Paint()
    private val paint7 = Paint()
    private val paint8 = Paint()
    private val paint9 = Paint()
    private val paint10 = Paint()

    private val dm = DisplayMetrics()
    private val width = dm.widthPixels
    private val height = dm.heightPixels

    private var sum by Delegates.notNull<Float>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        setContentView(R.layout.activity_main)

        val myView = MyView(this)
        setContentView(myView)

        val editTextTextPersonName = findViewById<EditText>(R.id.editTextTextPersonName)
        val editTextNumber1 = findViewById<EditText>(R.id.editTextNumber1)
        val editTextNumber2 = findViewById<EditText>(R.id.editTextNumber2)
        val button = findViewById<Button>(R.id.button)


        button.setOnClickListener {
            val intent = Intent(this, RouletteScreen::class.java)

            val etText1 = editTextTextPersonName.text.toString()
            val etText2 = editTextNumber1.text.toString()
            val etText3 = editTextNumber2.text.toString()

            //intent変数をつなげる(第一引数はキー,第二引数は渡したい変数)
            intent.putExtra("key1",etText1)
            intent.putExtra("key2",etText2)
            intent.putExtra("key3",etText3)
            startActivity(intent)
            finish()
        }
    }

    // Viewを継承したクラス
    internal inner class MyView(context: Context) : View(context) {
//        init {
//        }

        @RequiresApi(Build.VERSION_CODES.N)
        override fun onDraw(canvas: Canvas){
            rouletteMaking(canvas,1f,1f,2f,1f,1f,5f,4f,1f,1f,1f)
        }
    }


    @RequiresApi(Build.VERSION_CODES.N)
    fun rouletteMaking(canvas: Canvas, a:Float, b:Float?, c:Float?, d:Float?, e:Float?, f:Float?, g:Float?, h:Float?, i:Float?, j:Float?) {
        // 背景、半透明
        canvas.drawColor(Color.argb(0, 0, 0, 0))

        // 円
        paint.color = Color.argb(255, 0, 0, 0)
        paint.strokeWidth = 5f
        paint.isAntiAlias = true
        paint.style = Paint.Style.STROKE

        // 分岐
        if (height >= width) {
            // 円
            // (x1,y1,r,paint) 中心x1座標, 中心y1座標, r半径
            canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), (width / 2.5).toFloat(), paint)
            // 各項目
            val rect = RectF((width / 10).toFloat(), (height / 2 - 2 * width / 5).toFloat(), (9 * width / 10).toFloat(), (height / 2 + 2 * width / 5).toFloat())
            itemRation(canvas,rect, a, b, c, d, e, f, g, h, i, j)

        } else {
            // 円
            canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), (height / 2.5).toFloat(), paint)
            // 各項目
            val rect = RectF((width / 2 - 2 * height / 5).toFloat(), (height / 10).toFloat(), (width / 2 + 2 * height / 5).toFloat(), (9 * height / 10).toFloat())
            itemRation(canvas,rect,a, b, c, d, e, f, g, h, i, j)
        }

        //保存用Bitmap準備
        val image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        //新しいcanvasに保存用Bitmapをセット
        Canvas(image)
        //canvasに対して描画
        try {
            //出力ファイルを準備
            val fos = FileOutputStream(File("sample.png"))
            //PNG形式で出力
            image.compress(CompressFormat.PNG, 100, fos)
            fos.close()
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        }

    }

    private fun itemRation(canvas: Canvas, rect: RectF, a:Float, b:Float?, c:Float?, d:Float?, e:Float?, f:Float?, g:Float?, h:Float?, i:Float?, j:Float?){
        if (b != null && c != null && d != null && e != null && f != null && g != null && h != null && i != null && j != null) {
            sum = a + b + c + d + e + f + g + h + i + j
        } else if(b != null && c != null && d != null && e != null && f != null && g != null && h != null && i != null){
            sum = a + b + c + d + e + f + g + h + i
        } else if(b != null && c != null && d != null && e != null && f != null && g != null && h != null){
            sum = a + b + c + d + e + f + g + h
        } else if(b != null && c != null && d != null && e != null && f != null && g != null){
            sum = a + b + c + d + e + f + g
        } else if(b != null && c != null && d != null && e != null && f != null){
            sum = a + b + c + d + e + f
        } else if(b != null && c != null && d != null && e != null){
            sum = a + b + c + d + e
        } else if(b != null && c != null && d != null){
            sum = a + b + c + d
        } else if(b != null && c != null){
            sum = a + b + c
        } else if(b != null){
            sum = a + b
        } else{
            sum = a
        }

        val a0 : Float = a/sum
        val b0 : Float? = b?.div(sum)
        val c0 : Float? = c?.div(sum)
        val d0 : Float? = d?.div(sum)
        val e0 : Float? = e?.div(sum)
        val f0 : Float? = f?.div(sum)
        val g0 : Float? = g?.div(sum)
        val h0 : Float? = h?.div(sum)
        val i0 : Float? = i?.div(sum)
        val j0 : Float? = j?.div(sum)

        paint1.color = Color.argb(195, 233, 58, 36)
        canvas.drawArc(rect, -90F, a0*360, true, paint1)
        paint2.color = Color.argb(195, 234, 97, 25)
        if (b0 != null) {
            canvas.drawArc(rect, -90F+a0*360, b0*360, true, paint2)
        }
        paint3.color = Color.argb(195, 252, 202, 0)
        if (c0 != null) {
            canvas.drawArc(rect, -90F+(a0+ b0!!)*360, c0*360, true, paint3)
        }
        paint4.color = Color.argb(195, 184, 198, 1)
        if (d0 != null) {
            canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!)*360, d0*360, true, paint4)
        }
        paint5.color = Color.argb(195, 58, 149, 42)
        if (e0 != null) {
            canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!)*360, e0*360, true, paint5)
        }
        paint6.color = Color.argb(195, 10, 151, 114)
        if (f0 != null) {
            canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!+ e0!!)*360, f0*360, true, paint6)
        }
        paint7.color = Color.argb(195, 24, 158, 151)
        if (g0 != null) {
            canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!+ e0!!+ f0!!)*360, g0*360, true, paint7)
        }
        paint8.color = Color.argb(195, 89, 113, 157)
        if (h0 != null) {
            canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!+ e0!!+ f0!!+ g0!!)*360, h0*360, true, paint8)
        }
        paint9.color = Color.argb(195, 104, 68, 126)
        if (i0 != null) {
            canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!+ e0!!+ f0!!+ g0!!+ h0!!)*360, i0*360, true, paint9)
        }
        paint10.color = Color.argb(195, 224, 61, 114)
        if (j0 != null) {
            canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!+ e0!!+ f0!!+ g0!!+ h0!!+ i0!!)*360, j0*360, true, paint10)
        }
    }

}

試したこと

onCreate内のEditTextの定義文からbuttonのクリックリスナー部分をコメントアウトした状態で実行しても同様のエラーが出力されます。

補足情報(FW/ツールのバージョンなど)

Android Studio Chipmunk | 2021.2.1 Patch 1
Kotlin 1.7.0
macOS monterey 12.5.1

以下調べた内容などです
https://bluefish.orz.hm/sdoc/android_canvas.html
http://taketoma-labo.blogspot.com/2012/10/android.html
https://akira-watson.com/android/kotlin/canvas.html

0

No Answers yet.

Your answer might help someone💌