انواع عکس ها
به طور کلی دو نوع عکس داریم عکس هایی که بردار محور هستند و اصطلاحا بهشون 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 رو انتخاب میکنیم.
نکست رو میزنیم و در قسمت بعد گزینه import رو انتخاب میکنیم و سپس عکس به پوشه drowable-nodpi اضافه میشه.
راهنمایی
رایج ترین سایز برای افزودن عکس به 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 برای نمایش عکس های معمولی استفاده میکنیم.
بازخورد و دیدگاه ها
اولین نفری باشید که در این صفحه نظر میدهید