جت‌پک کامپوز در اندروید: نمایش عکس با تابع Image

جت‌پک کامپوز در اندروید: نمایش عکس با تابع Image

انواع عکس ها

به طور کلی دو نوع عکس داریم عکس هایی که بردار محور هستند و اصطلاحا بهشون Vector میگیم و عکس های Bitmap که به طور معمول در فضای مجازی می‌بینیم و دانلود می‌کنیم.

عکس های برداری (Vector Image)

این عکس ها به صورت برداری ترسیم میشن و با بزرگنمایی کیفیت خودشونو از دست نمیدن و ازشون به عنوان آیکون و... میتونیم استفاده کنیم، از جمله این عکس ها میتونیم به عکس های svg یا فایل هایی که به صورت xml با اندروید استادیو ساخته میشن اشاره کنیم.

عکس های Bitmap

با این عکس ها زیاد در فضای مجازی مواجه شدیم به این عکس ها در برنامه نویسی Bitmap گفته میشه. از جمله این عکس ها میتونیم به عکس هایی با فرمت png, jpeg و ... اشاره کنیم؛ کیفیت این عکس ها با بزرگنمایی و تغییر مقیاس تغییر می‌کنه.

تابع Image

در کامپوز یک تابع داریم به نام Image که وظیفش نمایش تصاویر در برنامه اندرویدیه.

فرم کلی

Image(
    painter: Painter|bitmap: ImageBitmap|vector: ImageVector,
    contentDescription: String,
    alpha: Float,
    alignment: Alignment,
    contentScale: ContentScale
    )
                

در نمودار زیر پارامتر های رایج تابع Image شرح داده شده است.

<<Fuction>>
androidx.compose.foundation.Image
Parameters
modifier: Modifier با استفاده از Modifier میتونیم Image رو سفارشی سازی کنیم.
painter: Painter با استفاده از Painter میتونیم عکس رو برای نمایش به Image پاس بدیم.
contentDescription: String برای عکس توضیحاتی در نظر میگیریم که قابل استفاده برای ابزار های accessibility باشه.
alpha: Float میزان شفافیت عکس رو به مشخص میکنه و مقدارش بین 0 تا 1 است.
alignment: Alignment محل قرار گیری عکس رو در چهارچوب Image مشخص میکنه.
contentScale: ContentScale مقیاس عکس رو تعیین میکنه (Crop, Fit, FillBounds, FillWidth, FillHeight, None, Inside).

افزودن عکس به منابع برنامه

به طور کلی دو نوع عکس داریم، عکس هایی که از نوع Vector هستن مثل svg ها و vector آیکون هایی که با اندروید استادیو میتونیم به صورت Vector ایجاد کنیم و عکس های Bitmap با فرمت png، jpeg و ... .

برای افزودن عکس به عنوان منابع مانند تصویر زیر ابتدا روی Resource Manager گوشه بالا سمت چپ (شماره ۱) کلیک کنید و سپس روی علامت به علاوه (شماره ۲) کلیک کنید و سپس گزینه Import Drawables رو بزنید (شماره ۳).

افزودن عکس به منابع برنامه در اندروید استادیو
افزودن عکس به منابع برنامه در اندروید استادیو

در پنجره جدید عکسی که میخوایم به برنامه اضافه کنیم رو در فایل های کامپیوتر پیدا و انتخاب میکنیم.

انتخاب عکس برای افزودن به منابع برنامه در اندروید استادیو
انتخاب عکس برای افزودن به منابع برنامه در اندروید استادیو

دستگاه های اندرویدی در ابعاد و صفحات مختلف تولید شدن و در اندروید استادیو به چند دسته تقسیم میشن: mdpi, hdpi, xhdpi, xxhdpi, ... برای راحتی میتونیم از nodpi استفاده کنیم؛ بنابراین مانند تصویر desity و سپس nodensity رو انتخاب میکنیم.

انتخاب density برای عکس جهت افزودن به drawable
انتخاب density برای عکس جهت افزودن به drawable

نکست رو میزنیم و در قسمت بعد گزینه import رو انتخاب میکنیم و سپس عکس به پوشه drowable-nodpi اضافه میشه.

پایان کار افزودن تصویر به drawable در اندروید استادیو.
پایان کار افزودن تصویر به drawable در اندروید استادیو.

راهنمایی

رایج ترین سایز برای افزودن عکس به drawable-nodpi سایز 1024 * 2400 پیکسل است.

painterResource

برای ایجاد یک نمونه از Painter میتونیم از تابع painterResource استفاده کنیم؛ برای اینکار ابتدا باید عکس رو در قسمت drawable در منابع برنامه اضافه کنیم، یک آی‌دی از نوع Integer به صورت خودکار برای عکس ایجاد میشه، میتونیم با استفاده از کلاس R آی‌دی عکس مورد نظر رو صدا بزنیم و به عنوان پارامتر به تابع painterResource پاس بدیم.

در مثال زیر میخوایم یک عکس رو در برنامه نمایش بدیم.

@Composable
fun myImage(resourceId: Int, modifier: Modifier = Modifier){
    Image(
        painter = painterResource(resourceId),
        contentDescription = null
        modifier = modifier.padding(16.dp).fillMaxWidth().height(400.dp)
    )
}
                    

برای کنترل بیشتر میتونیم به‌جای Painter از bitmap: ImageBitmap برای عکس های رایج و vector: ImageVector برای Vector استفاده کنیم.

contentDescription

پارامتر contentDescription توضیحاتی رو در مورد عکس میده و زمانی که برنامه نیاز به accessibility داره برنامه هایی مثل talkback میتونن عکس رو توضیح بدن.

مقداردهی این پارامتر اجباریه، زمانی که عکس به عنوان آیکون یا لوگو استفاده میشه نیازی میتونیم مقدار پارامتر رو null قرار بدیم و در غیر اینصورت باید توضیحاتی در مورد عکس به عنوان String قرار بدیم.

contentScale

از پارامتر contentScale برای تغییر مقیاس عکس در صفحه استفاده می‌کنیم، برای مقداردهی این پارامتر ContentScale رو صدا می‌زنیم و یکی از مقادیر ثابت Crop, Fit, None, FillWidth, FillHeight یا FillBounds رو صدا می‌زنیم.

Crop

مقیاس عکس رو به اندازه ای که تمام صفحه بشه افزایش میده و قسمت های اضافی عکس رو برش میده.

Fit

مقیاس عکس رو به اندازه ای که در صفحه جا بشه تنظیم میکنه، در این حالت ممکنه فضای خالی ایجاد بشه.

None

عکس رو به اندازه ابعاد واقعی خودش نمایش میده.

FillWidth

عکس رو به اندازه عرض صفحه (Image) کشیده می‌کنه.

FillHeight

عکس رو به اندازه ارتفاع صفحه (Image) کشیده می‌کنه.

FillBounds

عرض و ارتفاع عکس رو به اندازه صفحه کشیده میکنه.

در مثال زیر میخوایم یک عکس رو با مقیاس Crop نمایش بدیم.

@Composable
fun myImage(resourceId: Int, modifier: Modifier = Modifier){
    Image(
        painter = painterResource(resourceId),
        contentDescription = null,
        contentScale = ContentScale.Crop,
        modifier = modifier.padding(16.dp).fillMaxWidth().height(400.dp)
    )
}                   
                

خوندن عکس ها با ImageVector و ImageBitmap

میتونیم بجای Painter با ImageVector یا ImageBitmap عکس ها رو بخونیم؛ Painter به صورت خودکار نوع عکس رو تشخیص میده و عکس در تابع Image ترسیم میشه، استفاده از ImageVector یا ImageBitmap به‌جای Painter کنترل و انعطاف‌پذیری بیشتری به برنامه نویس میده.

ImageVector

زمانی که نوع عکس برداری باشه از ImageVector استفاده می‌کنیم.

فرم کلی:

@Composable
fun MyImage(id: Int, modifier: Modifier = Modifier){
    val vector = ImageVector.vectorResource(id)
    Image(
        vector = vector,
        contentDescription = null
    )
}
                    

ImageBitmap

زمانی که بخوایم عکس های Bitmap رو در Image نمایش بدیم از ImageBitmap استفاده میکنیم.

فرم کلی:

@Composable
fun MyImage(id: Int, modifier: Modifier = Modifier){
    val bitmap = ImageBitmap.imageResource(id)
    Image(
        bitmap = bitmap,
        contentDescription = null
    )
}
                    

مورد مطالعه (مثال) ها

میخوایم نقشه ایران رو به عنوان پس زمینه برنامه مسافت شهر ها در قسمت قبل اضافه کنیم.

میتونید عکس رو از اینجا دانلود و به منابع برنامه همونطور که در بالا گفته شد اضافه کنید.

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                IranCityDistances(modifier = Modifier
                    .padding(innerPadding)
                )
            }
        }
    }
}

@Composable
fun IranCityDistances(modifier: Modifier = Modifier){
    Box(modifier = modifier
        .padding()
        .fillMaxSize()
        .background(Color.White),
        contentAlignment = Alignment.Center
    ) {
        CityDistances(Modifier)
        IranMap()
    }
}

@Preview
@Composable
fun IranCityDistancesPreview(){
    IranCityDistances()
}

@Composable
fun IranMap(modifier: Modifier = Modifier){
    Image(
        painter = painterResource(R.drawable.blank_map_iran),
        contentDescription = null,
        contentScale = ContentScale.Crop,
        modifier = modifier.fillMaxWidth(),
        alpha = 0.45f,
        alignment = Alignment.Center
    )
}

@Composable
fun CityDistances(modifier: Modifier = Modifier) {
    Column(modifier) {
        CitiesRow()
        Distances()
    }
}

@Preview
@Composable
fun CityDistancesPreview() {
    CityDistances(Modifier)
}

@Composable
fun CitiesRow(modifier: Modifier = Modifier) {
    Row(
        modifier
            .fillMaxWidth()
            .background(Color(0xFFF5F5F5)),
        horizontalArrangement = Arrangement.End
    ) {
        for (city in cities) {
            Text(
                text = city,
                textAlign = TextAlign.Center,
                fontWeight = FontWeight.Bold,
                modifier = Modifier.padding(10.dp)
            )
        }
    }
}

@Composable
fun CitiesColumn(modifier: Modifier = Modifier) {
    Column(modifier) {
        for (city in cities)
            Text(
                text = city,
                color = Color(0xFFFAFAFA),
                modifier = Modifier.padding(bottom = 16.dp, top = 16.dp),
                fontWeight = FontWeight.Bold
            )
    }
}

@Composable
fun Distances(modifier: Modifier = Modifier) {

    Row(
        modifier
            .fillMaxWidth()
            .background(Color(0xFF212121)),
        horizontalArrangement = Arrangement.End
    ) {
        CitiesColumn()
        for (row in distances.indices) {

            Column {
                for (col in distances[row].indices) {
                    val distance = distances[row][col]
                    Text(
                        text = distance.toString(),
                        color = Color(0xFFFAFAFA),
                        textAlign = TextAlign.Center,
                        modifier = Modifier.padding(horizontal = 20.dp, vertical = 16.dp)
                    )
                }
            }
        }
    }
}
                

برنامه نهایی باید مشابه تصویر زیر باشه.

برنامه نمایش مسافت شهر ها با پس زمینه نقشه ایران.
برنامه نمایش مسافت شهر ها با پس زمینه نقشه ایران.

خلاصه

  • دو نوع عکس برداری و Bitmap داریم.
  • با استفاده از تابع Image میتونیم عکس ها رو در برنامه نمایش بدیم.
  • در تابع Image باید پارامتر contentDescription رو مقداردهی کنیم.
  • میتونیم بجای Painter از ImageVector و ImageBitmap به عنوان پارامتر Image استفاده کنیم.
  • از ImageVector برای نمایش عکس های برداری و از ImageBitmap برای نمایش عکس های معمولی استفاده میکنیم.

بازخورد و دیدگاه‌ ها

اولین نفری باشید که در این صفحه نظر می‌دهید

notifications برای اطلاع از جدیدترین مطالب و پست های مرتبط، عضو کانال تلگرام ما بشید.

arrow_drop_up
کپی شد!