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

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

新規登録して質問してみよう
ただいま回答率
85.48%
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

0回答

407閲覧

Canvasを画像として保存したい

active_vintage

総合スコア0

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2022/10/11 03:45

前提

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

実現したいこと

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

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

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

仮想デバイスのアラートダイアログ上で以下のように通知されます。
イメージ説明

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

該当のソースコード

kotlin

1package com.example.rouletteimage 2 3import android.content.Context 4import android.content.Intent 5import android.graphics.* 6import android.graphics.Bitmap.CompressFormat 7import android.os.Build 8import android.os.Bundle 9import android.util.DisplayMetrics 10import android.view.View 11import android.widget.Button 12import android.widget.EditText 13import androidx.annotation.RequiresApi 14import androidx.appcompat.app.AppCompatActivity 15import java.io.File 16import java.io.FileNotFoundException 17import java.io.FileOutputStream 18import java.io.IOException 19import kotlin.properties.Delegates 20 21 22class MainActivity : AppCompatActivity() { 23 24 private var paint: Paint = TODO() 25 private val paint1 = Paint() 26 private val paint2 = Paint() 27 private val paint3 = Paint() 28 private val paint4 = Paint() 29 private val paint5 = Paint() 30 private val paint6 = Paint() 31 private val paint7 = Paint() 32 private val paint8 = Paint() 33 private val paint9 = Paint() 34 private val paint10 = Paint() 35 36 private val dm = DisplayMetrics() 37 private val width = dm.widthPixels 38 private val height = dm.heightPixels 39 40 private var sum by Delegates.notNull<Float>() 41 42 override fun onCreate(savedInstanceState: Bundle?) { 43 super.onCreate(savedInstanceState) 44// setContentView(R.layout.activity_main) 45 46 val myView = MyView(this) 47 setContentView(myView) 48 49 val editTextTextPersonName = findViewById<EditText>(R.id.editTextTextPersonName) 50 val editTextNumber1 = findViewById<EditText>(R.id.editTextNumber1) 51 val editTextNumber2 = findViewById<EditText>(R.id.editTextNumber2) 52 val button = findViewById<Button>(R.id.button) 53 54 55 button.setOnClickListener { 56 val intent = Intent(this, RouletteScreen::class.java) 57 58 val etText1 = editTextTextPersonName.text.toString() 59 val etText2 = editTextNumber1.text.toString() 60 val etText3 = editTextNumber2.text.toString() 61 62 //intent変数をつなげる(第一引数はキー,第二引数は渡したい変数) 63 intent.putExtra("key1",etText1) 64 intent.putExtra("key2",etText2) 65 intent.putExtra("key3",etText3) 66 startActivity(intent) 67 finish() 68 } 69 } 70 71 // Viewを継承したクラス 72 internal inner class MyView(context: Context) : View(context) { 73// init { 74// } 75 76 @RequiresApi(Build.VERSION_CODES.N) 77 override fun onDraw(canvas: Canvas){ 78 rouletteMaking(canvas,1f,1f,2f,1f,1f,5f,4f,1f,1f,1f) 79 } 80 } 81 82 83 @RequiresApi(Build.VERSION_CODES.N) 84 fun rouletteMaking(canvas: Canvas, a:Float, b:Float?, c:Float?, d:Float?, e:Float?, f:Float?, g:Float?, h:Float?, i:Float?, j:Float?) { 85 // 背景、半透明 86 canvas.drawColor(Color.argb(0, 0, 0, 0)) 87 88 // 円 89 paint.color = Color.argb(255, 0, 0, 0) 90 paint.strokeWidth = 5f 91 paint.isAntiAlias = true 92 paint.style = Paint.Style.STROKE 93 94 // 分岐 95 if (height >= width) { 96 // 円 97 // (x1,y1,r,paint) 中心x1座標, 中心y1座標, r半径 98 canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), (width / 2.5).toFloat(), paint) 99 // 各項目 100 val rect = RectF((width / 10).toFloat(), (height / 2 - 2 * width / 5).toFloat(), (9 * width / 10).toFloat(), (height / 2 + 2 * width / 5).toFloat()) 101 itemRation(canvas,rect, a, b, c, d, e, f, g, h, i, j) 102 103 } else { 104 // 円 105 canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), (height / 2.5).toFloat(), paint) 106 // 各項目 107 val rect = RectF((width / 2 - 2 * height / 5).toFloat(), (height / 10).toFloat(), (width / 2 + 2 * height / 5).toFloat(), (9 * height / 10).toFloat()) 108 itemRation(canvas,rect,a, b, c, d, e, f, g, h, i, j) 109 } 110 111 //保存用Bitmap準備 112 val image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) 113 //新しいcanvasに保存用Bitmapをセット 114 Canvas(image) 115 //canvasに対して描画 116 try { 117 //出力ファイルを準備 118 val fos = FileOutputStream(File("sample.png")) 119 //PNG形式で出力 120 image.compress(CompressFormat.PNG, 100, fos) 121 fos.close() 122 } catch (e: FileNotFoundException) { 123 e.printStackTrace() 124 } catch (e: IOException) { 125 e.printStackTrace() 126 } 127 128 } 129 130 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?){ 131 if (b != null && c != null && d != null && e != null && f != null && g != null && h != null && i != null && j != null) { 132 sum = a + b + c + d + e + f + g + h + i + j 133 } else if(b != null && c != null && d != null && e != null && f != null && g != null && h != null && i != null){ 134 sum = a + b + c + d + e + f + g + h + i 135 } else if(b != null && c != null && d != null && e != null && f != null && g != null && h != null){ 136 sum = a + b + c + d + e + f + g + h 137 } else if(b != null && c != null && d != null && e != null && f != null && g != null){ 138 sum = a + b + c + d + e + f + g 139 } else if(b != null && c != null && d != null && e != null && f != null){ 140 sum = a + b + c + d + e + f 141 } else if(b != null && c != null && d != null && e != null){ 142 sum = a + b + c + d + e 143 } else if(b != null && c != null && d != null){ 144 sum = a + b + c + d 145 } else if(b != null && c != null){ 146 sum = a + b + c 147 } else if(b != null){ 148 sum = a + b 149 } else{ 150 sum = a 151 } 152 153 val a0 : Float = a/sum 154 val b0 : Float? = b?.div(sum) 155 val c0 : Float? = c?.div(sum) 156 val d0 : Float? = d?.div(sum) 157 val e0 : Float? = e?.div(sum) 158 val f0 : Float? = f?.div(sum) 159 val g0 : Float? = g?.div(sum) 160 val h0 : Float? = h?.div(sum) 161 val i0 : Float? = i?.div(sum) 162 val j0 : Float? = j?.div(sum) 163 164 paint1.color = Color.argb(195, 233, 58, 36) 165 canvas.drawArc(rect, -90F, a0*360, true, paint1) 166 paint2.color = Color.argb(195, 234, 97, 25) 167 if (b0 != null) { 168 canvas.drawArc(rect, -90F+a0*360, b0*360, true, paint2) 169 } 170 paint3.color = Color.argb(195, 252, 202, 0) 171 if (c0 != null) { 172 canvas.drawArc(rect, -90F+(a0+ b0!!)*360, c0*360, true, paint3) 173 } 174 paint4.color = Color.argb(195, 184, 198, 1) 175 if (d0 != null) { 176 canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!)*360, d0*360, true, paint4) 177 } 178 paint5.color = Color.argb(195, 58, 149, 42) 179 if (e0 != null) { 180 canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!)*360, e0*360, true, paint5) 181 } 182 paint6.color = Color.argb(195, 10, 151, 114) 183 if (f0 != null) { 184 canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!+ e0!!)*360, f0*360, true, paint6) 185 } 186 paint7.color = Color.argb(195, 24, 158, 151) 187 if (g0 != null) { 188 canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!+ e0!!+ f0!!)*360, g0*360, true, paint7) 189 } 190 paint8.color = Color.argb(195, 89, 113, 157) 191 if (h0 != null) { 192 canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!+ e0!!+ f0!!+ g0!!)*360, h0*360, true, paint8) 193 } 194 paint9.color = Color.argb(195, 104, 68, 126) 195 if (i0 != null) { 196 canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!+ e0!!+ f0!!+ g0!!+ h0!!)*360, i0*360, true, paint9) 197 } 198 paint10.color = Color.argb(195, 224, 61, 114) 199 if (j0 != null) { 200 canvas.drawArc(rect, -90F+(a0+ b0!!+ c0!!+ d0!!+ e0!!+ f0!!+ g0!!+ h0!!+ i0!!)*360, j0*360, true, paint10) 201 } 202 } 203 204}

試したこと

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

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問