1 package jp.sfjp.gokigen.a01c.liveview;
3 import android.content.Context;
4 import android.graphics.Bitmap;
5 import android.graphics.BitmapFactory;
6 import android.graphics.Canvas;
7 import android.graphics.Color;
8 import android.graphics.Paint;
9 import android.graphics.PointF;
10 import android.graphics.Rect;
11 import android.graphics.RectF;
12 import androidx.exifinterface.media.ExifInterface;
13 import androidx.preference.PreferenceDataStore;
15 import android.os.Looper;
16 import android.util.AttributeSet;
17 import android.util.DisplayMetrics;
18 import android.util.Log;
19 import android.util.TypedValue;
20 import android.view.MotionEvent;
21 import android.view.View;
22 import android.widget.ImageView;
25 import java.util.Timer;
26 import java.util.TimerTask;
28 import jp.co.olympus.camerakit.OLYCamera;
30 import jp.sfjp.gokigen.a01c.R;
31 import jp.sfjp.gokigen.a01c.liveview.dialog.IDialogController;
32 import jp.sfjp.gokigen.a01c.liveview.dialog.IDialogDrawer;
33 import jp.sfjp.gokigen.a01c.liveview.gridframe.GridFrameFactory;
34 import jp.sfjp.gokigen.a01c.liveview.gridframe.IGridFrameDrawer;
35 import jp.sfjp.gokigen.a01c.olycamerawrapper.ILevelGauge;
36 import jp.sfjp.gokigen.a01c.preference.IPreferenceCameraPropertyAccessor;
37 import jp.sfjp.gokigen.a01c.preference.PreferenceAccessWrapper;
40 * CameraLiveImageView :
41 * (OLYMPUS の ImageCaptureSample をカスタマイズ)
44 public class CameraLiveImageView extends View implements IImageDataReceiver, IAutoFocusFrameDisplay, ILiveImageStatusNotify, IDialogController
46 private final String TAG = toString();
48 private static final String EXIF_ORIENTATION = "Orientation";
50 private boolean showGridFeature = false;
51 private boolean showLevelGaugeFeature = false;
52 private ImageView.ScaleType imageScaleType;
53 private Bitmap imageBitmap;
54 private int imageRotationDegrees;
55 private boolean showingFocusFrame = false;
56 private IAutoFocusFrameDisplay.FocusFrameStatus focusFrameStatus;
57 private RectF focusFrameRect;
58 private Timer focusFrameHideTimer;
60 private IGridFrameDrawer gridFrameDrawer = null;
61 private ShowMessageHolder messageHolder;
63 private IDialogDrawer dialogDrawer = null;
64 private PreferenceDataStore preferences = null;
70 public CameraLiveImageView(Context context)
73 initComponent(context);
80 public CameraLiveImageView(Context context, AttributeSet attrs)
82 super(context, attrs);
83 initComponent(context);
90 public CameraLiveImageView(Context context, AttributeSet attrs, int defStyleAttr)
92 super(context, attrs, defStyleAttr);
93 initComponent(context);
97 * 初期化ロジック (preferenceからデータを読み出す)
99 private void initComponent(Context context)
101 messageHolder = new ShowMessageHolder();
103 imageScaleType = ImageView.ScaleType.FIT_CENTER;
105 preferences = new PreferenceAccessWrapper(context);
106 showGridFeature = preferences.getBoolean(IPreferenceCameraPropertyAccessor.SHOW_GRID_STATUS, true);
107 showLevelGaugeFeature = preferences.getBoolean(IPreferenceCameraPropertyAccessor.SHOW_LEVEL_GAUGE_STATUS, false);
109 int framingGridStatus = 0; // IPreferenceCameraPropertyAccessor.FRAME_GRID_DEFAULT_VALUE;
112 framingGridStatus = Integer.parseInt(preferences.getString(IPreferenceCameraPropertyAccessor.FRAME_GRID, IPreferenceCameraPropertyAccessor.FRAME_GRID_DEFAULT_VALUE));
118 gridFrameDrawer = GridFrameFactory.getGridFrameDrawer(framingGridStatus);
120 // ダミーのビットマップデータ読み込み...画面表示のテスト用ロジック
123 imageBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.momonga);
137 protected void onAttachedToWindow()
139 super.onAttachedToWindow();
147 protected void onDetachedFromWindow()
149 super.onDetachedFromWindow();
152 if (focusFrameHideTimer != null)
154 focusFrameHideTimer.cancel();
155 focusFrameHideTimer = null;
164 protected void onDraw(Canvas canvas)
166 super.onDraw(canvas);
173 if (dialogDrawer != null)
175 dialogDrawer.drawDialog(canvas);
179 // メッセージの表示 (Overwrite)
180 drawInformationMessages(canvas);
193 public float getContentSizeWidth() {
194 return getIntrinsicContentSizeWidth();
202 public float getContentSizeHeight() {
203 return getIntrinsicContentSizeHeight();
210 private float getIntrinsicContentSizeWidth()
212 if (imageBitmap == null)
216 return (imageBitmap.getWidth());
223 private float getIntrinsicContentSizeHeight()
225 if (imageBitmap == null)
229 return (imageBitmap.getHeight());
233 * Sets a image to view.
234 * (CameraLiveViewListenerImpl.IImageDataReceiver の実装)
236 * @param data A image of live-view.
237 * @param metadata A metadata of the image.
239 public void setImageData(byte[] data, Map<String, Object> metadata)
244 if (data != null && metadata != null)
249 bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
251 catch (OutOfMemoryError e)
257 // Acquire a rotation degree of image.
258 int orientation = ExifInterface.ORIENTATION_UNDEFINED;
261 if (metadata.containsKey(EXIF_ORIENTATION))
263 orientation = Integer.parseInt((String) metadata.get(EXIF_ORIENTATION));
272 case ExifInterface.ORIENTATION_ROTATE_90:
273 rotationDegrees = 90;
275 case ExifInterface.ORIENTATION_ROTATE_180:
276 rotationDegrees = 180;
278 case ExifInterface.ORIENTATION_ROTATE_270:
279 rotationDegrees = 270;
281 case ExifInterface.ORIENTATION_NORMAL:
286 imageBitmap = bitmap;
287 imageRotationDegrees = rotationDegrees;
293 * Returns a point which is detected by a motion event.
295 * @param event A motion event.
296 * @return A point in the view finder. if a point is equal to null, the point is out of the view finder.
298 public PointF getPointWithEvent(MotionEvent event)
300 if (event == null || imageBitmap == null)
305 PointF pointOnView = new PointF(event.getX(), event.getY());
306 PointF pointOnImage = convertPointFromViewArea(pointOnView);
309 if (imageRotationDegrees == 0 || imageRotationDegrees == 180) {
310 imageWidth = imageBitmap.getWidth();
311 imageHeight = imageBitmap.getHeight();
313 imageWidth = imageBitmap.getHeight();
314 imageHeight = imageBitmap.getWidth();
316 return (OLYCamera.convertPointOnLiveImageIntoViewfinder(pointOnImage, imageWidth, imageHeight, imageRotationDegrees));
320 * Returns whether a image area contains a specified point.
322 * @param point The point to examine.
323 * @return true if the image is not null or empty and the point is located within the rectangle; otherwise, false.
325 public boolean isContainsPoint(PointF point)
327 return ((point != null) && (new RectF(0, 0, 1, 1)).contains(point.x, point.y));
331 * Hides the forcus frame.
333 public void hideFocusFrame()
335 if (focusFrameHideTimer != null)
337 focusFrameHideTimer.cancel();
338 focusFrameHideTimer = null;
340 showingFocusFrame = false;
345 * Shows the focus frame.
347 * @param rect A rectangle of the focus frame on view area.
348 * @param status A status of the focus frame.
349 * @param duration A duration of the focus frame showing.
352 public void showFocusFrame(RectF rect, FocusFrameStatus status, double duration)
354 if (focusFrameHideTimer != null) {
355 focusFrameHideTimer.cancel();
356 focusFrameHideTimer = null;
359 showingFocusFrame = true;
360 focusFrameStatus = status;
361 focusFrameRect = rect;
366 focusFrameHideTimer = new Timer();
367 focusFrameHideTimer.schedule(new TimerTask() {
372 }, (long) (duration * 1000));
380 private void refreshCanvas()
382 if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
392 * @param canvas キャンバス
394 private void drawCanvas(Canvas canvas)
396 // Clears the canvas.
397 canvas.drawARGB(255, 0, 0, 0);
400 Bitmap bitmapToShow = imageBitmap;
401 if (bitmapToShow == null)
407 // Rotates the image.
408 int centerX = canvas.getWidth() / 2;
409 int centerY = canvas.getHeight() / 2;
410 canvas.rotate(imageRotationDegrees, centerX, centerY);
412 RectF viewRect = null;
414 // Calculate the viewport of bitmap.
415 if (imageScaleType == ImageView.ScaleType.FIT_CENTER)
417 viewRect = decideViewRect(canvas, bitmapToShow, imageRotationDegrees);
420 Rect imageRect = new Rect(0, 0, bitmapToShow.getWidth(), bitmapToShow.getHeight());
421 canvas.drawBitmap(bitmapToShow, imageRect, viewRect, null);
425 // Sorry, other scale types are not supported.
426 Log.v(TAG, "Sorry, other scale types are not supported. " + imageScaleType);
429 // Cancels rotation of the canvas.
430 canvas.rotate(-imageRotationDegrees, centerX, centerY);
434 if ((focusFrameRect != null) && (showingFocusFrame)) {
435 if (imageRotationDegrees == 0 || imageRotationDegrees == 180) {
436 drawFocusFrame(canvas, bitmapToShow.getWidth(), bitmapToShow.getHeight());
438 drawFocusFrame(canvas, bitmapToShow.getHeight(), bitmapToShow.getWidth());
442 if (viewRect != null)
445 if ((showGridFeature) && (gridFrameDrawer != null))
447 drawGridFrame(canvas, viewRect);
450 // レベルゲージ(デジタル水準器)の表示
451 if (showLevelGaugeFeature)
453 drawLevelGauge(canvas, viewRect);
462 private RectF decideViewRect(Canvas canvas, Bitmap bitmapToShow, int degree)
466 if ((degree == 0) || (degree == 180))
468 srcWidth = bitmapToShow.getWidth();
469 srcHeight = bitmapToShow.getHeight();
473 // Replaces width and height.
474 srcWidth = bitmapToShow.getHeight();
475 srcHeight = bitmapToShow.getWidth();
478 int maxWidth = canvas.getWidth();
479 int maxHeight = canvas.getHeight();
481 int centerX = canvas.getWidth() / 2;
482 int centerY = canvas.getHeight() / 2;
484 float widthRatio = maxWidth / (float) srcWidth;
485 float heightRatio = maxHeight / (float) srcHeight;
486 float smallRatio = Math.min(widthRatio, heightRatio);
490 if (widthRatio < heightRatio)
492 // Fits to maxWidth with keeping aspect ratio.
494 dstHeight = (int) (smallRatio * srcHeight);
498 // Fits to maxHeight with keeping aspect ratio.
499 dstHeight = maxHeight;
500 dstWidth = (int) (smallRatio * srcWidth);
503 final float halfWidth = dstWidth * 0.5f;
504 final float halfHeight = dstHeight * 0.5f;
505 if ((degree == 0) || (degree == 180))
509 centerY - halfHeight,
510 centerX - halfWidth + dstWidth,
511 centerY - halfHeight + dstHeight));
514 // Replaces the width and height.
516 centerX - halfHeight,
518 centerX - halfHeight + dstHeight,
519 centerY - halfWidth + dstWidth));
525 * @param canvas キャンバス
526 * @param imageWidth 幅
527 * @param imageHeight 高さ
529 private void drawFocusFrame(Canvas canvas, float imageWidth, float imageHeight)
531 //Log.v(TAG, "drawFocusFrame() :" + focusFrameStatus);
533 // Calculate the rectangle of focus.
534 RectF focusRectOnImage = OLYCamera.convertRectOnViewfinderIntoLiveImage(focusFrameRect, imageWidth, imageHeight, imageRotationDegrees);
535 RectF focusRectOnView = convertRectFromImageArea(focusRectOnImage);
537 // Draw a rectangle to the canvas.
538 Paint focusFramePaint = new Paint();
539 focusFramePaint.setStyle(Paint.Style.STROKE);
540 switch (focusFrameStatus) {
542 focusFramePaint.setColor(Color.WHITE);
546 focusFramePaint.setColor(Color.GREEN);
550 focusFramePaint.setColor(Color.RED);
554 focusFramePaint.setColor(Color.YELLOW);
557 float focusFrameStrokeWidth = 2.0f;
558 DisplayMetrics dm = getResources().getDisplayMetrics();
559 float strokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, focusFrameStrokeWidth, dm);
560 focusFramePaint.setStrokeWidth(strokeWidth);
561 canvas.drawRect(focusRectOnView, focusFramePaint);
567 * @param canvas キャンバスエリア
568 * @param viewRect 表示領域
570 private void drawGridFrame(Canvas canvas, RectF viewRect)
573 if ((imageRotationDegrees == 0) || (imageRotationDegrees == 180)) {
574 gridRect = new RectF(viewRect);
576 float height = viewRect.right - viewRect.left;
577 float width = viewRect.bottom - viewRect.top;
578 float left = (canvas.getWidth() / 2.0f) - (width / 2.0f);
579 float top = (canvas.getHeight() / 2.0f) - (height / 2.0f);
580 gridRect = new RectF(left, top, left + width, top + height);
583 Paint framePaint = new Paint();
584 framePaint.setStyle(Paint.Style.STROKE);
585 framePaint.setAntiAlias(true);
587 //DisplayMetrics dm = getResources().getDisplayMetrics();
588 //float strokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1.0f, dm);
589 //framePaint.setStrokeWidth(strokeWidth);
590 framePaint.setStrokeWidth(0.0f);
591 framePaint.setColor(gridFrameDrawer.getDrawColor());
592 gridFrameDrawer.drawFramingGrid(canvas, gridRect, framePaint);
599 private void drawLevelGauge(Canvas canvas, RectF viewRect)
601 ILevelGauge levelGauge = messageHolder.getLevelGauge();
602 if (levelGauge == null)
604 // デジタル水準器がとれない場合は、何もしない
609 int height = (int) viewRect.bottom; // canvas.getHeight();
610 int width = (int) viewRect.right; // canvas.getWidth();
611 int centerX = width / 2;
612 int centerY = height / 2;
614 //float maxBandWidth = width / 3.0f; // ゲージの最大長 (画面の 1/3 ぐらい)
615 float maxBandHeight = height / 3.0f; // ゲージの最大長 (画面の 1/3 ぐらい)
616 int barWidthInitial = 4; // 表示するゲージの幅(の初期値)
617 int barWidth; // 実際に表示するゲージの幅
619 Paint paint = new Paint();
622 float verticalValue = levelGauge.getLevel(ILevelGauge.LevelArea.LEVEL_VERTICAL);
623 float verticalSize = verticalValue / 60.0f * maxBandHeight; // 45度で切り替わるはずだが、一応...
624 if (Math.abs(verticalSize) < 1.0f)
626 // 線引き限界以下、水平検出とする (この時の線は倍の長さにする)
628 barWidth = barWidthInitial * 2;
632 barWidth = barWidthInitial;
634 paint.setStrokeWidth(barWidth);
635 paint.setColor(levelGauge.getLevelColor(verticalValue));
636 canvas.drawLine((width - barWidth), centerY, (width - barWidth), (centerY + verticalSize), paint);
639 float horizontalValue = levelGauge.getLevel(ILevelGauge.LevelArea.LEVEL_HORIZONTAL);
640 paint.setStrokeWidth(2.0f);
641 paint.setAntiAlias(true);
642 paint.setColor(levelGauge.getLevelColor(horizontalValue));
643 if ((imageRotationDegrees == 0) || (imageRotationDegrees == 180))
646 float YY = canvas.getHeight() / 2.0f; // centerY
647 float diffY = (float) Math.sin(Math.toRadians(horizontalValue)) * (float) centerX;
648 canvas.drawLine(0, (YY + diffY), width, (YY - diffY), paint);
653 float XX = canvas.getWidth() / 2.0f; // centerX
654 float diffX = (float) Math.sin(Math.toRadians(horizontalValue)) * (float) centerY;
655 canvas.drawLine((XX + diffX), 0, (XX - diffX), canvas.getHeight(), paint);
660 float horizontalValue = levelGauge.getLevel(ILevelGauge.LevelArea.LEVEL_HORIZONTAL);
661 float horizontalSize = horizontalValue / 60.0f * maxBandWidth; // 45度ぐらいで切り替わるはずだが、一応...
662 if (Math.abs(horizontalSize) < 1.0f)
664 // 線引き限界以下、水平検出とする (この時の線は倍の長さにする)
665 horizontalSize = 1.0f;
666 barWidth = barWidthInitial * 2;
670 barWidth = barWidthInitial;
672 paint.setStrokeWidth(barWidth);
673 paint.setColor(levelGauge.getLevelColor(horizontalValue));
674 canvas.drawLine(centerX, (height - barWidth), (centerX + horizontalSize), (height - barWidth), paint);
681 private void drawInformationMessages(Canvas canvas)
685 if (imageBitmap != null)
687 // ビットマップの表示エリアに合わせて位置をチューニングする
688 viewRect = decideViewRect(canvas, imageBitmap, 0);
693 viewRect = new RectF(5.0f, 0.0f, canvas.getWidth() - 5.0f, canvas.getHeight() - 55.0f);
697 message = messageHolder.getMessage(ShowMessageHolder.MessageArea.CENTER);
698 if ((message != null)&&(message.length() > 0))
700 Paint paint = new Paint();
701 paint.setColor(messageHolder.getColor(ShowMessageHolder.MessageArea.CENTER));
702 paint.setTextSize(messageHolder.getSize(ShowMessageHolder.MessageArea.CENTER));
703 paint.setAntiAlias(true);
704 paint.setShadowLayer(5.0f, 3.0f, 3.0f, Color.BLACK); // これで文字に影をつけたい
705 Paint.FontMetrics fontMetrics = paint.getFontMetrics();
706 float cx = (canvas.getWidth() / 2.0f) - (paint.measureText(message) / 2.0f);
707 float cy = (canvas.getHeight() / 2.0f) - ((fontMetrics.ascent + fontMetrics.descent) / 2.0f);
708 canvas.drawText(message, cx, cy, paint);
712 message = messageHolder.getMessage(ShowMessageHolder.MessageArea.UPLEFT);
713 if ((message != null)&&(message.length() > 0))
715 Paint paintUp = new Paint();
716 paintUp.setColor(messageHolder.getColor(ShowMessageHolder.MessageArea.UPLEFT));
717 paintUp.setTextSize(messageHolder.getSize(ShowMessageHolder.MessageArea.UPLEFT));
718 paintUp.setAntiAlias(true);
719 paintUp.setShadowLayer(5.0f, 3.0f, 3.0f, Color.BLACK); // これで文字に影をつけたい
720 Paint.FontMetrics fontMetrics = paintUp.getFontMetrics();
721 canvas.drawText(message, viewRect.left + 3.0f, viewRect.top + (fontMetrics.descent - fontMetrics.ascent), paintUp);
725 message = messageHolder.getMessage(ShowMessageHolder.MessageArea.UPRIGHT);
726 if ((message != null)&&(message.length() > 0))
728 Paint paintUp = new Paint();
729 paintUp.setColor(messageHolder.getColor(ShowMessageHolder.MessageArea.UPRIGHT));
730 paintUp.setTextSize(messageHolder.getSize(ShowMessageHolder.MessageArea.UPRIGHT));
731 paintUp.setAntiAlias(true);
732 paintUp.setShadowLayer(5.0f, 3.0f, 3.0f, Color.BLACK); // これで文字に影をつけたい
733 float width = paintUp.measureText(message);
734 Paint.FontMetrics fontMetrics = paintUp.getFontMetrics();
735 canvas.drawText(message, (viewRect.right - 3.0f) - width, viewRect.top + (fontMetrics.descent - fontMetrics.ascent), paintUp);
739 message = messageHolder.getMessage(ShowMessageHolder.MessageArea.LOWLEFT);
740 if ((message != null)&&(message.length() > 0))
742 Paint paint = new Paint();
743 paint.setColor(messageHolder.getColor(ShowMessageHolder.MessageArea.LOWLEFT));
744 paint.setTextSize(messageHolder.getSize(ShowMessageHolder.MessageArea.LOWLEFT));
745 paint.setAntiAlias(true);
746 paint.setShadowLayer(5.0f, 3.0f, 3.0f, Color.BLACK); // これで文字に影をつけたい
747 Paint.FontMetrics fontMetrics = paint.getFontMetrics();
748 canvas.drawText(message, viewRect.left + 3.0f, viewRect.bottom - fontMetrics.bottom, paint);
752 message = messageHolder.getMessage(ShowMessageHolder.MessageArea.LOWRIGHT);
753 if ((message != null)&&(message.length() > 0))
755 Paint paint = new Paint();
756 paint.setColor(messageHolder.getColor(ShowMessageHolder.MessageArea.LOWRIGHT));
757 paint.setTextSize(messageHolder.getSize(ShowMessageHolder.MessageArea.LOWRIGHT));
758 paint.setAntiAlias(true);
759 paint.setShadowLayer(5.0f, 3.0f, 3.0f, Color.BLACK); // これで文字に影をつけたい
760 float width = paint.measureText(message);
761 Paint.FontMetrics fontMetrics = paint.getFontMetrics();
762 canvas.drawText(message, (viewRect.right - 3.0f) - width, viewRect.bottom - fontMetrics.bottom, paint);
767 message = messageHolder.getMessage(ShowMessageHolder.MessageArea.UPCENTER);
768 if ((message != null)&&(message.length() > 0))
770 Paint paintUp = new Paint();
771 paintUp.setColor(messageHolder.getColor(ShowMessageHolder.MessageArea.UPCENTER));
772 paintUp.setTextSize(messageHolder.getSize(ShowMessageHolder.MessageArea.UPCENTER));
773 paintUp.setAntiAlias(true);
774 paintUp.setShadowLayer(5.0f, 3.0f, 3.0f, Color.BLACK); // これで文字に影をつけたい
775 float width = paintUp.measureText(message) / 2.0f;
776 Paint.FontMetrics fontMetrics = paintUp.getFontMetrics();
777 canvas.drawText(message, (viewRect.centerX()) - width, viewRect.top + (fontMetrics.descent - fontMetrics.ascent), paintUp);
781 message = messageHolder.getMessage(ShowMessageHolder.MessageArea.LOWCENTER);
782 if ((message != null)&&(message.length() > 0))
784 Paint paint = new Paint();
785 paint.setColor(messageHolder.getColor(ShowMessageHolder.MessageArea.LOWCENTER));
786 paint.setTextSize(messageHolder.getSize(ShowMessageHolder.MessageArea.LOWCENTER));
787 paint.setAntiAlias(true);
788 paint.setShadowLayer(5.0f, 3.0f, 3.0f, Color.BLACK); // これで文字に影をつけたい
789 float width = paint.measureText(message) / 2.0f;
790 Paint.FontMetrics fontMetrics = paint.getFontMetrics();
791 canvas.drawText(message, (viewRect.centerX()) - width, viewRect.bottom - fontMetrics.bottom, paint);
795 message = messageHolder.getMessage(ShowMessageHolder.MessageArea.CENTERLEFT);
796 if ((message != null)&&(message.length() > 0))
798 Paint paint = new Paint();
799 paint.setColor(messageHolder.getColor(ShowMessageHolder.MessageArea.CENTERLEFT));
800 paint.setTextSize(messageHolder.getSize(ShowMessageHolder.MessageArea.CENTERLEFT));
801 paint.setAntiAlias(true);
802 paint.setShadowLayer(5.0f, 3.0f, 3.0f, Color.BLACK); // これで文字に影をつけたい
803 Paint.FontMetrics fontMetrics = paint.getFontMetrics();
804 float cy = (canvas.getHeight() / 2.0f) - ((fontMetrics.ascent + fontMetrics.descent) / 2.0f);
805 canvas.drawText(message, viewRect.left + 3.0f, cy, paint);
809 message = messageHolder.getMessage(ShowMessageHolder.MessageArea.CENTERRIGHT);
810 if ((message != null)&&(message.length() > 0))
812 Paint paint = new Paint();
813 paint.setColor(messageHolder.getColor(ShowMessageHolder.MessageArea.CENTERRIGHT));
814 paint.setTextSize(messageHolder.getSize(ShowMessageHolder.MessageArea.CENTERRIGHT));
815 paint.setAntiAlias(true);
816 paint.setShadowLayer(5.0f, 3.0f, 3.0f, Color.BLACK); // これで文字に影をつけたい
817 float width = paint.measureText(message);
818 Paint.FontMetrics fontMetrics = paint.getFontMetrics();
819 float cy = (canvas.getHeight() / 2.0f) - ((fontMetrics.ascent + fontMetrics.descent) / 2.0f);
820 canvas.drawText(message, (viewRect.right - 3.0f) - width, cy, paint);
826 * Converts a point on image area to a point on view area.
828 * @param point A point on image area. (e.g. a live preview image)
829 * @return A point on view area. (e.g. a touch panel view)
831 private PointF convertPointFromImageArea(PointF point) {
832 if (imageBitmap == null) {
836 float viewPointX = point.x;
837 float viewPointY = point.y;
838 float imageSizeWidth;
839 float imageSizeHeight;
840 if (imageRotationDegrees == 0 || imageRotationDegrees == 180) {
841 imageSizeWidth = imageBitmap.getWidth();
842 imageSizeHeight = imageBitmap.getHeight();
844 imageSizeWidth = imageBitmap.getHeight();
845 imageSizeHeight = imageBitmap.getWidth();
847 float viewSizeWidth = this.getWidth();
848 float viewSizeHeight = this.getHeight();
849 float ratioX = viewSizeWidth / imageSizeWidth;
850 float ratioY = viewSizeHeight / imageSizeHeight;
853 switch (imageScaleType)
856 viewPointX *= ratioX;
857 viewPointY *= ratioY;
859 case FIT_CENTER: // go to next label.
861 scale = Math.min(ratioX, ratioY);
864 viewPointX += (viewSizeWidth - imageSizeWidth * scale) / 2.0f;
865 viewPointY += (viewSizeHeight - imageSizeHeight * scale) / 2.0f;
868 scale = Math.max(ratioX, ratioY);
871 viewPointX += (viewSizeWidth - imageSizeWidth * scale) / 2.0f;
872 viewPointY += (viewSizeHeight - imageSizeHeight * scale) / 2.0f;
875 viewPointX += viewSizeWidth / 2.0 - imageSizeWidth / 2.0f;
876 viewPointY += viewSizeHeight / 2.0 - imageSizeHeight / 2.0f;
881 return new PointF(viewPointX, viewPointY);
885 * Converts a point on view area to a point on image area.
887 * @param point A point on view area. (e.g. a touch panel view)
888 * @return A point on image area. (e.g. a live preview image)
890 private PointF convertPointFromViewArea(PointF point) {
891 if (imageBitmap == null) {
895 float imagePointX = point.x;
896 float imagePointY = point.y;
897 float imageSizeWidth;
898 float imageSizeHeight;
899 if (imageRotationDegrees == 0 || imageRotationDegrees == 180) {
900 imageSizeWidth = imageBitmap.getWidth();
901 imageSizeHeight = imageBitmap.getHeight();
903 imageSizeWidth = imageBitmap.getHeight();
904 imageSizeHeight = imageBitmap.getWidth();
906 float viewSizeWidth = this.getWidth();
907 float viewSizeHeight = this.getHeight();
908 float ratioX = viewSizeWidth / imageSizeWidth;
909 float ratioY = viewSizeHeight / imageSizeHeight;
912 switch (imageScaleType) {
914 imagePointX /= ratioX;
915 imagePointY /= ratioY;
917 case FIT_CENTER: // go to next label.
919 scale = Math.min(ratioX, ratioY);
920 imagePointX -= (viewSizeWidth - imageSizeWidth * scale) / 2.0f;
921 imagePointY -= (viewSizeHeight - imageSizeHeight * scale) / 2.0f;
922 imagePointX /= scale;
923 imagePointY /= scale;
926 scale = Math.max(ratioX, ratioY);
927 imagePointX -= (viewSizeWidth - imageSizeWidth * scale) / 2.0f;
928 imagePointY -= (viewSizeHeight - imageSizeHeight * scale) / 2.0f;
929 imagePointX /= scale;
930 imagePointY /= scale;
933 imagePointX -= (viewSizeWidth - imageSizeWidth) / 2.0f;
934 imagePointY -= (viewSizeHeight - imageSizeHeight) / 2.0f;
939 return new PointF(imagePointX, imagePointY);
943 * Converts a rectangle on image area to a rectangle on view area.
945 * @param rect A rectangle on image area. (e.g. a live preview image)
946 * @return A rectangle on view area. (e.g. a touch panel view)
948 private RectF convertRectFromImageArea(RectF rect)
950 if (imageBitmap == null)
955 PointF imageTopLeft = new PointF(rect.left, rect.top);
956 PointF imageBottomRight = new PointF(rect.right, rect.bottom);
958 PointF viewTopLeft = convertPointFromImageArea(imageTopLeft);
959 PointF viewBottomRight = convertPointFromImageArea(imageBottomRight);
961 return (new RectF(viewTopLeft.x, viewTopLeft.y, viewBottomRight.x, viewBottomRight.y));
968 public void setShowGridFrame(boolean isShowGridFeature)
970 showGridFeature = isShowGridFeature;
973 preferences.putBoolean(IPreferenceCameraPropertyAccessor.SHOW_GRID_STATUS, showGridFeature);
986 public void toggleShowGridFrame()
988 setShowGridFrame(!showGridFeature);
995 public void setShowLevelGauge(boolean isShowLevelGaugeFeature)
997 Log.v(TAG, "setShowLevelGauge : " + isShowLevelGaugeFeature);
998 showLevelGaugeFeature = isShowLevelGaugeFeature;
1001 preferences.putBoolean(IPreferenceCameraPropertyAccessor.SHOW_LEVEL_GAUGE_STATUS, showLevelGaugeFeature);
1002 ILevelGauge levelGauge = messageHolder.getLevelGauge();
1003 if (levelGauge == null)
1005 // デジタル水準器がとれない場合は、何もしない
1006 Log.v(TAG, "setShowLevelGauge : levelGauge is null.");
1009 levelGauge.updateLevelGaugeChecking(isShowLevelGaugeFeature);
1013 e.printStackTrace();
1022 public void toggleShowLevelGauge()
1024 setShowLevelGauge(!showLevelGaugeFeature);
1032 public boolean isShowLevelGauge()
1034 return (showLevelGaugeFeature);
1042 public boolean isShowGrid()
1044 return (showGridFeature);
1052 public IMessageDrawer getMessageDrawer()
1054 return (messageHolder);
1062 public void showDialog(IDialogDrawer dialogDrawer)
1064 this.dialogDrawer = dialogDrawer;
1072 public void hideDialog()
1074 this.dialogDrawer = null;
1083 public boolean touchedPosition(float posX, float posY)
1085 return ((dialogDrawer != null)&&(dialogDrawer.touchedPosition(posX, posY)));