یکی از موضوعاتی که هر برنامهنویس اندروید باید در ذهن خود داشته باشد، کار با دوربین در برنامه نویسی اندروید است. این موضوع یکی از چندین مثال و آموزش در این حوزه است که برای توسعه دهندگان اهمیت زیادی دارد. زمانی اهمیت آن بیشتر میشود که اپلیکیشن شما از دوربین استفاده کند و هرچقدر بخواهید قابلیتهای بیشتری اضافه کنید طبیعی است که مهارت شما باید بیشتر باشد. در ادامه بهطور مفصل توضیح دادهایم و ابتدا برای اینکه ذهن شما آماده شود این کار را با مسائل مقدماتی شروع میکنیم.
کار با دوربین در برنامه نویسی اندروید: نقش دوربین در تلفن همراه
دوربین یکی از قسمتهای اصلی تلفنهای همراه امروزی است که روزبهروز هم درحال پیشرفت است. خبر خوب این است که این پیشرفت بیشتر بعد سختافزاری را هدف میگیرد یعنی از نظر لنز یا تعداد دوربین است. البته نباید اینطور برداشت کنید که کار با دوربین در برنامهنویسی اندروید از نظر نرمافزاری و کدها تغییر نمیکند اما همچنان چهارچوبهای مشخصی باقی میماند.
امروزه کاربرد دوربین فراتر از استفادههای آن در گذشته است و تنها برای عکس گرفتن یا فیلمبرداری از آن استفاده نمیشود. شناسایی اشیا، عکسبرداری سهبعدی، اعتبارسنجی و امنیت (مثلاً شناسایی تصویر برای بازشدن قفل صفحه) و واقعیت مجازی تعدادی از کاربردهای امروزی آن هستند. با توضیحاتی که داده شد، متوجه میشوید که این ابزار سختافزاری کمک زیادی به توسعه میکند. اگر کار با دوربین در برنامه نویسی اندروید را به خوبی بدانید میتوانید در ساخت اپلیکیشنها از آن استفاده کنید.
کار با دوربین در برنامه نویسی اندروید: بررسی آمار و ارقام
اولین تلفن همراه که دوربین داشت در سال 2000 در ژاپن با نام J-SH04 معرفی شد و یک صنعت سودآور است که با نرخ 6 درصد در سال رشد میکند. به دلیل افزایش تعداد لنز دوربین در تلفنهای همراه پیشبینی میشود که این صنعت به خوبی رشد کند. تعداد اپلیکیشنهایی که در ارتباط با این واحد سختافزاری ساخته میشوند بسیار زیاد است که نشان میدهد فرصت خوبی وجود دارد. با این توضیحات، تا کار با دوربین در برنامه نویسی اندروید میتواند یک آموزش مناسب و هدفمند باشد.
حوزه | مجموع ارزش بازار | نرخ رشد |
ساخت لنز و دوربین | 4 میلیارد دلار | 6 درصد |
ساخت اپلیکیشن | 154 میلیارد دلار | 11 درصد |
روش کار به چه صورت است؟
پس از آن که با نقش و اهمیت ارتباط با دوربین بهعنوان یک واحد سختافزاری را متوجه شدید، وقت آن است تا رویکرد خود را توضیح دهیم. این موضوع از آن جهت اهمیت دارد که ذهن شما را برای برخورد با مسائل و توضیحات منظم میکند و یک آماده سازی پیش از آموزش است.
طبیعی است که توضیحات ما بر اساس APIهای دوربین اندروید است تا کار با دوربین در برنامه نویسی اندروید را به خوبی متوجه شوید. ابتدا توضیح میدهیم که API چه قابلیتهای تعریف شدهای دارد و این کار را با چند مثال ساده انجام میدهیم. خوب است بدانید که اپلیکیشنهای زیادی از API منسوخ استفاده میکنند و باید حواس خود را به سمت نمونههای جدیدتر معطوف کنیم. API جدید با نام Camera2 API شناخته میشود که در API مرحله 21 معرف شد تا مورد استفاده توسعهدهندگان قرار بگیرد.
توصیه میکنیم که Android SDK خود را بهروز نگه دارید پس قبل از شروع کار از این موضوع مطمئن شوید. از آن جایی که پکیج Camera2 API به تازگی منتشر شده آموزشها و مثال های زیادی وجود ندارد بنابراین این آموزش اهمیت زیادی حتی برای توسعه بهصورت حرفهای دارد. همچنین سعی کنید Camera2Basic را بررسی کنید که در آن توضیحات کلی شامل پیش نمایش، ذخیره تصاویر و مانند آن وجود دارد. اکنون میتوانیم آموزش کار با دوربین در برنامه نویسی اندروید را شروع کنیم.
کار با دوربین در برنامه نویسی اندروید: تنظیمات کلی دوربین
برای دسترسی اپلیکیشن به دوربین و قابلیتهای آن، باید از کاربر بخواهید اجازه دسترسی آن به دوربین را بدهد. این کار همانطور که میدانید با نمایش یک پیام و کسب اجازه است. از زمان اندروید نسخه 6، API سطح 23 کنترل بیشتری برای رد یا قبول دسترسی به دوربین دارند. قبلا این اجازه در هنگام نصب باید داده میشد که مانند الان پویا و دقیق نبود.
به همین دلیل در اولین قدم کار با دوربین در برنامه نویسی اندروید توصیه میشود که ابتدا دسترسیها و مجوزهای فعلی اپلیکیشن را شناسایی کنید. در مرحله بعد نیز آن را در برابر سرویسهای محافظت شده یا دادهها تست کنید و اگر لازم بود، اجازه دسترسی را به صورت پویا یا Dynamic ایجاد کنید.
این کار باعث میشود زمانی که اپلیکیشن درحال کار است دیگر متوقف نشود. در فایل AndroidManifest.xml چند اجازه دسترسی و ویژگی وجود دارد که میتوانید از آنها استفاده کنید. این موارد شامل برای کنترل دوربین و ذخیره عکس یا دوربین بر روی یک حافظه خارجی مانند SD Card است. به دستورات زیر دقت کنید:
<uses-permission android_name=”android.permission.CAMERA” />
<uses-permission android_name=
“android.permission.WRITE_EXTERNAL_STORAGE” />
<uses-feature android_name=
“android.hardware.camera” android_required=”true” />
<uses-feature android_name=
“android.hardware.camera.autofocus” />
در ابتدای اپلیکیشن یعنی همان ابتدای کار با دوربین در برنامه نویسی اندروید، باید مطمئن شویم که دسترسیها در فایل manifest داده شده است. مسیر فایل بهصورت Manifest.permission.CAMERA و Manifest.permission.WRITE_EXTERNAL_STORAGE که برای خود دوربین و فضای ذخیرهسازی است. اگر اینطور نباشد، باید به صورت پویا یعنی requestPermissions() این کار را انجام دهید. زمانی که همه دسترسیها داده شد برنامه کار خود را شروع میکند.
حالا میبینید که کار با دوربین در برنامه نویسی اندروید چندان هم پیچیده نیست. دستور زیر نشان میدهد که چطور به صورت پویا درخواست دسترسی کنید:
public class TutorialOnCamera extends Activity {
static final int REQUEST_PERMISSION_CAMERA = 1001;
static final int REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE =
1002;
int permissionCount = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.examples);
// Request permissions at runtime
permissionCount = 0;
if (checkSelfPermission(Manifest.permission.CAMERA) !=
PackageManager.PERMISSION_GRANTED)
requestPermissions(new String[]
{Manifest.permission.CAMERA},
REQUEST_PERMISSION_CAMERA);
else
permissionCount++;
if (checkSelfPermission
(Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED)
requestPermissions(new String[]
{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE);
else
permissionCount++;
// Start the default camera intent
Button button_send_to_another = (Button)
findViewById(R.id.button_by_intent);
button_send_to_another.setOnClickListener
(new View.OnClickListener() {
// @Override
public void onClick(View arg0) {
if (permissionCount >= 2)
…code snipped…
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions,
grantResults);
switch (requestCode) {
case REQUEST_PERMISSION_CAMERA:
case REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE:
if (grantResults[0] ==
PackageManager.PERMISSION_GRANTED)
permissionCount++;
default:
break;
}
}
}
استفاده با تنظیمات پیشفرض
مرحله بعدی آموزش کار با دوربین در برنامه نویسی اندروید برای کسانی است که حوصله زیادی ندارند. این کار با استفاده از صدوریک Intent اندروید انجام میشود. این روش درواقع فعال کردن اپلیکیشن پیشفرض دوربین با استفاده از برنامهای است که خودتان ساختهاید. اگر نمیخواهید کار پیچیدهای انجام دهید (برای مثال رابط کاربری سفارشی) و فقط به پردازش دوربین نیاز دارید این روش مناسب است.
برای این منظور از یک Intent اندروید که توسط خود سیستم در اختیار شما قرار داده شده استفاده کنید و از تصویر یا فیلم استفاده کنید. کد آن بهصورت MediaStore.ACTION_IMAGE_CAPTURE است و کار را با دستور startActivityForResult شروع کنید. کار با دوربین در برنامه نویسی اندروید در این شرایطمیتواند با اضافه کردن یک مقصد برای ذخیره سازی بهتر هم شود. برای مثال دستور cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri) می تواند به شما کمک کند.
در غیر اینصورت یک بیتمپ یا bitmap برای تصویری که گرفته شده ایجاد میشود و به مسیر زیر برمیگردد:
Bitmap b = (data.getExtras()).getParcelable(“data”)
برای ساده شدن کار با دوربین در برنامه نویسی اندروید، نتیجه را بر روی صفحه نمایش هم نشان میدهیم که در زیر دستور آن وجود دارد.
public class DefaultCameraByIntent extends Activity {
static final int ID_ACT_CAMERA = 20001;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.defcam);
issueCameraIntent();
}
private void issueCameraIntent() {
Intent cameraIntent = new Intent
(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, ID_ACT_CAMERA);
}
protected void onActivityResult(int requestCode,
int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ID_ACT_CAMERA &&
resultCode == RESULT_OK) {
Bitmap b = (data.getExtras()).getParcelable(“data”);
ImageView iv = (ImageView)findViewById(R.id.iv);
iv.setImageBitmap(b);
}
}
}
تلفن همراه شما از چه مشخصاتی پشتیبانی میکند؟
استفاده از API معرفی شده یعنی Camera2 برای کار با دوربین در برنامه نویسی اندروید مزیتهای زیادی ایجاد کرد. عملکرد بهتر از نظر سختافزار، مدیریت بهتر و سریعتر چند عکس و چند دوربین، فیلتر و افکتهای بیشتر و مواردی مانند آن نمونههایی از این مزیتها است.
با استفاده از CameraManager باید لیست دوربین های دستگاه خود را استخراج کنید(در صورتیکه چند دوربین دارد یا قدیمی و تک دوربین باشد تفاوتی ندارد). با کار با دوربین در برنامه نویسی اندروید به صورت بهتر و مدیریت شده، با CameraCharacteristics میتوانید یک query از مشخصات هر دوربین ایجاد کنید که در زیر نشان داده شده است. دستور کامل در صفحه رسمی Camera2 API وجود دارد.
public class Camera2Characts extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cam2char);
CameraManager manager = (CameraManager)
getSystemService(CAMERA_SERVICE);
String result = “”;
try {
for (String cid : manager.getCameraIdList()) {
CameraCharacteristics cc =
manager.getCameraCharacteristics(cid);
Integer camdir = cc.get
(CameraCharacteristics.LENS_FACING);
if (camdir != null && camdir ==
CameraCharacteristics.LENS_FACING_FRONT)
result += (“Camera ” + cid +
“: value=” + camdir + “, facing frontn”);
else
result += (“Camera ” + cid + “: value=” +
camdir + “, not facing frontn”);
Boolean flash = cc.get
(CameraCharacteristics.FLASH_INFO_AVAILABLE);
if (flash != null && flash == true)
result += (“Camera ” + cid + “: value=” + flash +
“, flash availablen”);
else
result += (“Camera ” + cid + “: value=” + flash +
“, flash not availablen”);
List<CameraCharacteristics.Key<?>> keys = cc.getKeys();
result += (“Camera ” + cid + “: ” + keys.toString() +
“nn”);
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
result = result.replaceAll(“CameraCharacteristics.Key
(“, “”);
result = result.replaceAll(“)”, “”);
TextView tv = (TextView) findViewById(R.id.tv);
tv.setText(result);
}
}
تصویر برداری با Camera2 API
کار با دوربین در برنامه نویسی اندروید به همینجا ختم نمیشود و هنوز به یک قسمت مهم یعنی تصویربرداری نرسیدهایم. اکنون با یک مثال نشان میدهیم که چطور با API معرفی شده عکس بگیرید. ابتدا با یک Panel زنده یا Live با استفاده از TextureView و بهصورت زیر به دست میآید:
<com.androidlet.cliu.tutorialoncamera.MyTextureView
android_id=”@+id/mtv”
android_layout_width=”fill_parent”
android_layout_height=”fill_parent”
android_layout_alignParentEnd=”true”
android_layout_alignParentBottom=”true” />
در دستوراتی که در ادامه وجود دارد، روش گرفتن عکس با مشخص کردن فایل و مسیر خروجی نشان داده شده است. وقتی کاربرد دکمه را لمس میکند، نرم افزار وارد حالت startCapture() می شود و فرمت نتایج را در setCaptureResult() مشخص می کند.
در مرحله بعد عملیات های اصلی به روش captureStillPicture() اجرا می شود. زمانی که عکس آماده شد، با استفاده از SavePhotoToFile() در فضای ذخیره سازی خارجی ذخیره می شود. سپس فایل مربوط به عکس مجدد بارگذاری یا Load میشود و مقیاس آن طبق loadPhotoIntoView() کوچکتر می شود (تبدیل به thumbnail).
public class Camera2Take extends Activity {
private static final String TAG = “TutorialOnCamera”;
private static String mFileFolder = “”;
private static String mFilename = “cam2.jpg”;
private static boolean mFileFolderOK = false;
private static File mFile;
private static Bitmap mBitmap = null;
private MyTextureView mTextureView;
…
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cam2take);
mTextureView = (MyTextureView)findViewById(R.id.mtv);
// Create file folder
mFileFolder = Environment.getExternalStorageDirectory() +
“/TutorialOnCamera/”;
File sddir = new File(mFileFolder);
if (!sddir.mkdirs()) {
if (sddir.exists())
mFileFolderOK = true;
else
mFileFolderOK = false;
} else
mFileFolderOK = true;
mFile = new File(mFileFolder + mFilename);
// Take Photos with Camera2
Button button_takephoto = (Button)
findViewById(R.id.button_takephoto);
button_takephoto.setOnClickListener(new
View.OnClickListener() {
// @Override
public void onClick(View arg0) {
startCapture();
}
});
}
private void loadPhotoIntoView() {
if (mBitmap != null)
mBitmap.recycle();
try {
FileInputStream fis = new FileInputStream(mFileFolder +
mFilename);
BufferedInputStream bis = new BufferedInputStream(fis);
mBitmap = BitmapFactory.decodeStream(bis);
bis.close();
fis.close();
Matrix m = new Matrix();
m.setScale(50.0f / (float)mBitmap.getWidth(),
50.0f / (float)mBitmap.getHeight());
mBitmap = Bitmap.createBitmap(mBitmap, 0, 0,
mBitmap.getWidth(),
mBitmap.getHeight(),
m, true);
ImageView thumb = (ImageView)findViewById(R.id.thumb);
thumb.setImageBitmap(mBitmap);
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
…
private final ImageReader.OnImageAvailableListener
mOnImageAvailableListener
= new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader ir) {
mHandler.post(new SavePhotoToFile(ir.acquireNextImage(),
mFile));
}
};
private void setCaptureResult(int width, int height) {
CameraManager manager = (CameraManager)getSystemService
(Context.CAMERA_SERVICE);
try {
for (String cameraId : manager.getCameraIdList()) {
…
mImageReader.setOnImageAvailableListener
(mOnImageAvailableListener, mHandler);
…
}
} catch (CameraAccessException e) {
e.printStackTrace();
} catch (NullPointerException e) {
Log.d(TAG, “setCaptureResult(): NullPointerException”);
}
}
private void captureStillPicture() {
try {
…
CameraCaptureSession.CaptureCallback CaptureCallback
= new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted
(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
endCapture();
loadPhotoIntoView();
}
};
mCaptureSession.stopRepeating();
mCaptureSession.abortCaptures();
mCaptureSession.capture(captureBuilder.build(),
CaptureCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void startCapture() {
…
}
private void endCapture() {
…
}
…
private static class SavePhotoToFile implements Runnable {
private final Image mImage;
private final File mFile;
SavePhotoToFile(Image image, File file) {
mImage = image;
mFile = file;
}
…
}
…
}
مزیتهای استفاده از Camera2 API
استفاده از این API برای کار با دوربین در برنامه نویسی اندروید مزیتهای زیادی دارند که عبارتند از:
- به روز رسانی و رفع مشکلات
- کارایی و کیفیت بیشتر
- امکان سازگاری بیشتر با لنزهای جدید
- منسوخ شدن نسخههای قبلی
چند ایده برای کار با دوربین در برنامه نویسی اندروید
برای ایجاد اپلیکیشنهای مرتبط با دوربین، میتوان از ایدههای زیر استفاده کرد که البته تعدادی از قبل وجود دارند.
- دوربین با برنامه نویسی و عملکرد بهتر
- دوربین با فیلتر و افکتهای بیشتر
- اپلیکیشن تشخیص چهره برای ورود
- برنامههای ویرایش عکس
- ساخت بازی با ایدههای خلاقانه
در انتها سه پرسش و پاسخ زیر را بررسی میکنیم.
1- چرا دوربین و برنامه نویسی اندروید؟ به دلیل امکان توسعه اپلیکیشنهای زیاد با استفاده از آن
2- کار را چطور شروع کنیم؟ با استفاده از APIهای از قبل موجود
3- بهترین استاندارد کدام است؟ Camera2 API
نتیجهگیری و کلام آخر
در این مقاله تلاش کردیم تا درباره کار با دوربین در برنامه نویسی اندروید توضیح دهیم. برای این منظور ابتدا از اهمیت و پتانسیلهای دوربین بهعنوان یک واحد سخت افزاری صحبت کردیم. سپس حالتهای مختلف استفاده از آن با مثالهای ساده بررسی شد.
هیچ دیدگاهی نوشته نشده است.