Хочу вывести превью камеры на дисплей и нарисовать квадрат в области тача. Превью получить удалось, но не могу грамотно реализовать отрисовку. Все время ошибки, плюс иногда получается, что сама графика показывается на несколько секунд и пропадает. Как лучше реализовать это все?
ShowCamera.java
public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback {
Camera camera;
SurfaceHolder holder;
Path path;
volatile boolean running = false;
public ShowCamera(Context context, Camera camera) {
super(context);
this.camera = camera;
holder = getHolder();
holder.addCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Camera.Parameters params = camera.getParameters();
List<Camera.Size> sizes = params.getSupportedPictureSizes();
Camera.Size mSize = null;
for(Camera.Size size : sizes){
mSize = size;
}
//change orientation
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){
params.set("orientation","portrait");
camera.setDisplayOrientation(90);
params.setRotation(90);
}
else{
params.set("orientation","landscape");
camera.setDisplayOrientation(0);
params.setRotation(0);
}
params.setPictureSize(mSize.width,mSize.height);
camera.setParameters(params);
try{
camera.setPreviewDisplay(holder);
camera.startPreview();
}
catch(IOException e){
e.printStackTrace();
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
Button btn_run;
Button btn_select;
TextView tv;
FrameLayout camera_preview;
Camera camera;
ShowCamera showCamera;
DrawView drawView;
float x_touch;
float y_touch;
int X_touch;
int Y_touch;
String sDown;
public boolean camera_state = true;
private boolean onSelect = false;
private boolean canSelect = false;
private boolean has_camera = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// элементы из activity_main
btn_run = findViewById(R.id.btn_run);
btn_select = findViewById(R.id.btn_selectStar);
camera_preview = findViewById(R.id.camera_preview);
drawView = findViewById(R.id.drawViewxml);
tv = findViewById(R.id.tv);
// проверка на наличие камеры
if (!checkCameraHardware(MainActivity.this)) {
has_camera = false;
Toast toast = Toast.makeText(this, "Камера не найдена", Toast.LENGTH_LONG);
toast.show();
}
// open camera
camera = Camera.open();
showCamera = new ShowCamera(this, camera);
camera_preview.addView(showCamera);
camera_preview.setVisibility(View.VISIBLE);
addTouchListener();
}
public void btnRunOnClick(View view) {
if (has_camera) {
if (camera_state) {
camera_state = false;
btn_run.setText("Остановить");
camera_preview.setVisibility(View.VISIBLE);
Toast toast = Toast.makeText(this, "Камера остановлена", Toast.LENGTH_SHORT);
toast.show();
camera.startPreview();
} else {
camera_state = true;
btn_run.setText("Запустить");
camera_preview.setVisibility(View.VISIBLE);
Toast toast = Toast.makeText(this, "Камера запущена", Toast.LENGTH_SHORT);
toast.show();
camera.stopPreview();
}
} else {
Toast toast = Toast.makeText(this, "Камера не может быть запущена, \nпоскольку ее нет", Toast.LENGTH_LONG);
toast.show();
}
}
public void btnSelectStarOnClick(View view) {
if (onSelect) {
onSelect = false;
canSelect = true;
btn_select.setText("Прекратить");
Toast toast = Toast.makeText(this, "Выберите объект", Toast.LENGTH_SHORT);
toast.show();
} else {
onSelect = true;
canSelect = false;
btn_select.setText("Выбрать");
Toast toast = Toast.makeText(this, "Выбор запрещен", Toast.LENGTH_SHORT);
toast.show();
}
}
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}
private void addTouchListener(){
camera_preview.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(canSelect){
x_touch = event.getX();
y_touch = event.getY();
X_touch = Math.round(x_touch);
Y_touch = Math.round(y_touch);
sDown = "Down: " + X_touch + "," + Y_touch;
tv.setText(sDown);
}
return false;
}
});
}
}
Создайте класс наследник View для прорисовки поверх превью. Этом может быть и тач и фокус и всякие рожки-усики.. Что то типа такого:
public class CameraOverlay extends View{
public CameraOverlay(Context context) {
super(context);
}
public CameraOverlay(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*тут чето рисуете*/
}
@Override
public boolean onTouchEvent(MotionEvent event) {
/*улавливаем касание*/
}
}
Далее класс ViewGroup в котором юзаете камеру и выше созданный класс
public class CameraPreview extends ViewGroup {
private CameraOverlay overlay;
private ShowCamera camera;
public CameraPreview(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
В разметке получаем такое:
<com.example.CameraPreview
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/preview">
<com.example.CameraOverlay
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/overlay"/>
</com.example.CameraPreview>
В принципе все.
В следующем примере блок main (синезелёный градиент) обрезается при помощи clip-path и принимает форму сердечкаОднако видно, что он обрезается...
В IE11 из-за вложенного флексбокса текст не переходит на следующую строку, а растягивается на весь контент, если же поставить дляitem width:100%, блоки...
Не знал, как точно сформировать вопрос, поэтому сразу прошу прощения
Суть в том, что svg фигура в clipPath отрисовывается как есть, по тем самым размерам, с которыми создана