android 3d画廊(转)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 3d画廊(转)相关的知识,希望对你有一定的参考价值。

参考技术A public class GalleryActivity2extends AppCompatActivity

private LayoutInflatermLayoutInflater;

    private ViewPagermVp;

    private int[]mImg =new int[]R.mipmap.pic4, R.mipmap.pic5, R.mipmap.pic6, R.mipmap.pic4, R.mipmap.pic5;

    @Override

    protected void onCreate(@Nullable Bundle savedInstanceState)

super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_gallery);

        mLayoutInflater = LayoutInflater.from(this);

        mVp = (ViewPager) findViewById(R.id.vp_gallery_vp);

        mVp.setAdapter(new MyAdapter());

        mVp.setOffscreenPageLimit(mImg.length);//设置预加载数量

        mVp.setPageMargin(-150);//控制两幅图之间的间距

        mVp.setPageTransformer(true, new ZoomOutPageTransformer());

        //viewPager左右两边滑动无效的处理

        findViewById(R.id.ll_gallery_outer).setOnTouchListener(new View.OnTouchListener()

@Override

            public boolean onTouch(View view, MotionEvent motionEvent)

return mVp.dispatchTouchEvent(motionEvent);

           

);

   

class MyAdapterextends PagerAdapter

@Override

        public int getCount()

return mImg.length;

       

@Override

        public boolean isViewFromObject(View view, Object object)

return view == object;

       

@Override

        public ObjectinstantiateItem(ViewGroup container, final int position)

View view =mLayoutInflater.inflate(R.layout.item_img, container, false);

            ImageView img = view.findViewById(R.id.img_item_img);

            //img.setImageResource(R.mipmap.sea);

            img.setImageResource(mImg[position]);

            img.setScaleType(ImageView.ScaleType.CENTER_CROP);

            img.setOnClickListener(new View.OnClickListener()

@Override

                public void onClick(View v)

Toast.makeText(GalleryActivity2.this, "" +position, Toast.LENGTH_SHORT).show();

               

);

            container.addView(view);

            return view;

       

@Override

        public void destroyItem(ViewGroup container, int position, Object object)

container.removeView((View) object);

       



//设置切换动画

public class ZoomOutPageTransformerimplements ViewPager.PageTransformer

//自由控制缩放比例

    private static final float MAX_SCALE =1f;

    private static final float MIN_SCALE =0.6f;//0.85f

    @Override

    public void transformPage(View page, float position)

if (position <=1)

float scaleFactor =MIN_SCALE + (1 - Math.abs(position)) * (MAX_SCALE -MIN_SCALE);

            page.setScaleX(scaleFactor);

            if (position >0)

page.setTranslationX(-scaleFactor *2);

            else if (position <0)

page.setTranslationX(scaleFactor *2);

           

page.setScaleY(scaleFactor);

        else

page.setScaleX(MIN_SCALE);

            page.setScaleY(MIN_SCALE);

       





activity_gallery.xml

    android:id="@+id/ll_gallery_outer"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:clipChildren="false"

    android:orientation="vertical">

        android:id="@+id/vp_gallery_vp"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:layout_margin="50dp"

        android:clipChildren="false" />

item_img.xml

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:gravity="center"

    android:orientation="vertical">

        android:id="@+id/img_item_img"

        android:layout_width="200dp"

        android:scaleType="centerCrop"

        android:layout_height="100dp"

        android:src="@mipmap/pic4" />

Android - 如何从相机或画廊拍照

【中文标题】Android - 如何从相机或画廊拍照【英文标题】:Android - How to take a picture from camera or gallery 【发布时间】:2013-11-16 17:26:46 【问题描述】:

我想请用户从相机或设备中的现有图片(图库或其他)中拍照。我该怎么做?

我已经实现了下面的解决方案,看起来效果很好,但是文档很混乱,所以我想知道是否有更好的解决方案。

另外,请查看此相关帖子。在那里您将看到如何获取图像路径或位图:Get/pick an image from Android's built-in Gallery app programmatically

因此,在我的解决方案中,您将创建一个 TakePictureHelper 对象并执行以下操作。

假设您显示一个对话框,用户可以在其中选择“相机”或“其他”。当用户选择一个选项时,您可以调用takeFromCamera()takeFromOther()。当拍照(或不拍照)时,onActivityResult() 方法将被调用。在那里你可以调用retrievePicture,它会返回图片的Uri,如果没有拍照则返回null。

如果我不清楚,请告诉我您的想法、分享想法或问我任何问题。

非常感谢!

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TakePictureHelper 

    public final static int REQUEST_CAMERA = 1;
    public final static int REQUEST_OTHER = 2;

    private Uri cameraImageUri;

    /**
     * Request picture from camera using the given title
     */
    public void takeFromCamera(Activity activity, String title)
    
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File cameraImageOutputFile = new File(
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                createCameraImageFileName());
        cameraImageUri = Uri.fromFile(cameraImageOutputFile);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraImageUri);
        activity.startActivityForResult(Intent.createChooser(intent, title), REQUEST_CAMERA);
    

    /**
     * Request picture from any app (gallery or whatever) using the given title
     */
    public void takeFromOther(Activity activity, String title)
    
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        activity.startActivityForResult(Intent.createChooser(intent, title), REQUEST_OTHER);
    

    /**
     * Retrieve the picture, taken from camera or gallery.
     *
     * @return the picture Uri, or null if no picture was taken.
     */
    public Uri retrievePicture(Activity activity, int requestCode, int resultCode, Intent data)
    
        Uri result = null;

        if (resultCode == Activity.RESULT_OK) 

            if (requestCode == REQUEST_OTHER) 
                result = data.getData();
             else if (requestCode == REQUEST_CAMERA) 
                result = cameraImageUri;
            
        

        return result;
    

    private String createCameraImageFileName() 
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        return timeStamp + ".jpg";
    

【问题讨论】:

【参考方案1】:

根据@yurezcv 的回答,这是我想出的(最重要的是如何在 onActivityResult 中检索图像):

private List<File> cameraImageFiles;

private void popImageChooser()
    // Camera.
    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    final PackageManager packageManager = getPackageManager();
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);

    cameraImageFiles = new ArrayList<File>();

    int i=0;
    for(ResolveInfo res : listCam) 
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.MEDIA_IGNORE_FILENAME, ".nomedia");

        File cameraImageOutputFile = new File(
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                createCameraImageFileName());
        cameraImageFiles.add(cameraImageOutputFile);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraImageFiles.get(i)));
        i++;

        cameraIntents.add(intent);
    

    // Filesystem.
    final Intent galleryIntent = new Intent();
    galleryIntent.setType("image/*");
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

    // Chooser of filesystem options.
    final Intent chooserIntent = Intent.createChooser(galleryIntent, getString(R.string.attach_images_title));

    // Add the camera options.
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]));
    startActivityForResult(chooserIntent, ACTIVITY_REQUEST_CODE_IMAGE);



protected void onActivityResult(int requestCode, int resultCode, 
           Intent imageReturnedIntent) 
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent); 

    switch(requestCode)  
    case ACTIVITY_REQUEST_CODE_IMAGE:
        if(resultCode == RESULT_OK)

            Uri uri = null;
            if(imageReturnedIntent == null)   //since we used EXTRA_OUTPUT for camera, so it will be null

                for(int i=0;i<cameraImageFiles.size();i++)
                    if(cameraImageFiles.get(i).exists())
                        uri = Uri.fromFile(cameraImageFiles.get(i));
                        break;
                    
                
                Log.d("attachimage", "from camera: "+uri);
            
            else   // from gallery
                uri = imageReturnedIntent.getData();
                Log.d("attachimage", "from gallery: "+uri.toString());
            

            if(uri != null)
                attachImage(uri);
            
        
    

【讨论】:

createCameraImageFileName() 在哪里,它有什么作用? @AnasAzeem 它只是为从相机拍摄的新图像文件生成一个字符串名称。你可以随心所欲地写它【参考方案2】:

这个解决方案对我有用:

private void addPhoto()    
       // Camera.
    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);     
    final PackageManager packageManager = getPackageManager();
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
    for(ResolveInfo res : listCam) 
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.MEDIA_IGNORE_FILENAME, ".nomedia");

        cameraIntents.add(intent);
    

    // Filesystem.
    final Intent galleryIntent = new Intent();
    galleryIntent.setType("image/*");
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

    // Chooser of filesystem options.
    final Intent chooserIntent = Intent.createChooser(galleryIntent, getString(R.string.add_new));

    // Add the camera options.
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]));
    startActivityForResult(chooserIntent, YOUR_REQUEST_CODE);

它创建一个意图对话框,其中包含从相机、文件系统等选择图像的所有可能变体。

【讨论】:

谢谢。如何获取onActivityResult 中的图像文件?如果它来自相机或其他应用程序,你也会这样做吗?【参考方案3】:

Hay un detalle que no se ha dicho y es que actualmente el tema de la orientación de la cámara es un desastre cuando lo que se hace esguardar la captura y luego leerla de disco para mostrarla。 Esto es así porque los fabricantes、como HTC、Samsung 等没有 se ponen de acuerdo en seguir el 标准。 En este caso, puede (y depende del dispositivo), ser necesario corregir la imagen usando la informationación EXIF de la misma para que no se muestre rotada por ejemlo, en un ImageView。

Si la imagen de la cámara no la guardamos sino que en la vuelta leemos del Bundle los datos guardados en la key "data", la imagen se mostrará bien。

Otra cosa que yo haría si guardamos la foto en disco, es hacer que esta se vea en la galería para que el usuario la pueda ver y borrar directamente (ver MediaScannerConnectionClient)

Yo lo he hecho tal como se ve en el código que pongo abajo。 Permite hacerlo bien por la galería ó, tomando una captura con la cámara。 (para algunas tareas he usado la librería pública en GitHub https://github.com/javocsoft/javocsoft-toolbox/)

package com.example.getpicture;

import java.io.File;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import es.javocsoft.android.lib.toolbox.ToolBox;
import es.javocsoft.android.lib.toolbox.media.MediaScannerNotifier;

public class MainActivity extends Activity 

private final int PICTURE_TAKEN_FROM_CAMERA = 1;
private final int PICTURE_TAKEN_FROM_GALLERY = 2;

private Button btncamera = null;
private Button btngallery = null;
private ImageView pictureZone = null;
private boolean storeImage = false;
private File outFile = null;


@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    pictureZone = (ImageView)findViewById(R.id.pictureZone);
    btncamera = (Button)findViewById(R.id.btncamera);
    btngallery = (Button)findViewById(R.id.btngallery);


    addEvents();



private void addEvents()
    btncamera.setOnClickListener(new OnClickListener() 

        @Override
        public void onClick(View v) 
            getPictureFromCamera();         
        
    );

    btngallery.setOnClickListener(new OnClickListener() 

        @Override
        public void onClick(View v) 
            getPictureFromGallery();            
        
    );
   

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);

    Bitmap takenPictureData = null;

    switch(requestCode)

        case PICTURE_TAKEN_FROM_CAMERA:             
            if(resultCode==Activity.RESULT_OK) 
                takenPictureData = handleResultFromCamera(data);
                           
            break;
        case PICTURE_TAKEN_FROM_GALLERY:                
            if(resultCode==Activity.RESULT_OK) 
                takenPictureData = handleResultFromChooser(data);                   
            
            break;          
    

    //And show the result in the image view.
    if(takenPictureData!=null)
        pictureZone.setImageBitmap(takenPictureData);
           



//AUXILIAR

private Bitmap handleResultFromChooser(Intent data)
    Bitmap takenPictureData = null;

    Uri photoUri = data.getData();
    if (photoUri != null)
        try 
            //We get the file path from the media info returned by the content resolver
            String[] filePathColumn = MediaStore.Images.Media.DATA;
            Cursor cursor = getContentResolver().query(photoUri, filePathColumn, null, null, null); 
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String filePath = cursor.getString(columnIndex);
            cursor.close();

            takenPictureData = ToolBox.media_getBitmapFromFile(new File(filePath));

        catch(Exception e)
            ToolBox.dialog_showToastAlert(this, "Error getting selected image.", false);
        
    

    return takenPictureData;


private Bitmap handleResultFromCamera(Intent data)
    Bitmap takenPictureData = null;

    if(data!=null)
        //Android sets the picture in extra data.
        Bundle extras = data.getExtras();
        if(extras!=null && extras.get("data")!=null)
            takenPictureData = (Bitmap) extras.get("data");
        
    else
        //If we used EXTRA_OUTPUT we do not have the data so we get the image
        //from the output.
        try
            takenPictureData = ToolBox.media_getBitmapFromFile(outFile);
            takenPictureData = ToolBox.media_correctImageOrientation(outFile.getAbsolutePath());
        catch(Exception e)
            ToolBox.dialog_showToastAlert(this, "Error getting saved taken picture.", false);
        
    

    if(storeImage)
        //We add the taken picture file to the gallery so user can see the image directly                   
        new MediaScannerNotifier(this,outFile.getAbsolutePath(),"image/*", false);
    

    return takenPictureData;


private void getPictureFromCamera()
    boolean cameraAvailable = ToolBox.device_isHardwareFeatureAvailable(this, PackageManager.FEATURE_CAMERA);
    if(cameraAvailable && 
        ToolBox.system_isIntentAvailable(this, MediaStore.ACTION_IMAGE_CAPTURE))

        Intent takePicIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        //We prepare the intent to store the taken picture
        try
            File outputDir = ToolBox.storage_getExternalPublicFolder(Environment.DIRECTORY_PICTURES, "testApp", true);
            outFile = ToolBox.storage_createUniqueFileName("cameraPic", ".jpg", outputDir);

            takePicIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outFile));             
            storeImage = true;
        catch(Exception e)
            ToolBox.dialog_showToastAlert(this, "Error setting output destination.", false);
        

        startActivityForResult(takePicIntent, PICTURE_TAKEN_FROM_CAMERA);
    else
        if(cameraAvailable)
            ToolBox.dialog_showToastAlert(this, "No application that can receive the intent camera.", false);
        else
            ToolBox.dialog_showToastAlert(this, "No camera present!!", false);
        
    


private void getPictureFromGallery()
    /*
    //This allows to select the application to use when selecting an image.
    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
    i.setType("image/*");
    startActivityForResult(Intent.createChooser(i, "Escoge una foto"), PICTURE_TAKEN_FROM_GALLERY);
    */

    //This takes images directly from gallery
    Intent gallerypickerIntent = new Intent(Intent.ACTION_PICK);
    gallerypickerIntent.setType("image/*");
    startActivityForResult(gallerypickerIntent, PICTURE_TAKEN_FROM_GALLERY); 

El布局es:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="#f2f2f2"    
tools:context=".MainActivity" >

<ImageView
    android:id="@+id/pictureZone"
    android:layout_
    android:layout_
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"

    android:src="@drawable/ic_launcher" />

<Button
    android:id="@+id/btncamera"
    android:layout_
    android:layout_
    android:layout_marginTop="36dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:text="Camera" />

<Button
    android:id="@+id/btngallery"
    android:layout_
    android:layout_
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    android:text="Pick it" />

<TextView
    android:id="@+id/textView1"
    android:layout_
    android:layout_
    android:layout_above="@+id/btngallery"
    android:layout_centerHorizontal="true"
    android:text="Choose an option"
    android:textStyle="bold"
    android:textAppearance="?android:attr/textAppearanceMedium" />

Y por último en el manifest hace falta como no, los permisos adecuados:

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

不敬礼。

【讨论】:

我们不会说您的语言。请英语【参考方案4】:

我找到了一种更好更简单的方法来从相机或画廊拍照,即使用这个库https://android-arsenal.com/details/1/3623

您可以点击上面的链接或按照以下步骤操作:

在你的项目中使用这个库的步骤是:

    添加对 Gradle 的依赖:

    编译'com.frosquivel:magicalcamera:4.4'

    实现代码:

    PermissionGranted permissionGranted = new PermissionGranted(this); MagicalCamera magicCamera = new MagicalCamera(this, permissionGranted); //参数this,是当前活动 //拍照权限,如果用户勾选拒绝则为假 permissionGranted.checkCameraPermission(); //用于在设备内存中搜索和写入照片 //普通或SD内存 permissionGranted.checkReadExternalPermission(); permissionGranted.checkWriteExternalPermission();

    调用从相机拍照:

    magicalCamera.takePhoto();

    调用从图库中选择照片:

    magicalCamera.selectedPicture("my_header_name");

    重写 OnActivityResult();获取Bitmap和Path的方法:

    public void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);
    magicalCamera.resultPhoto(requestCode, resultCode, data);//with this form you obtain the bitmap
    Bitmap bitmap = magicalCamera.getPhoto();
    imageView.setImageBitmap(bitmap);
    //if you need path of bitmap use this code
    String path = magicalCamera.savePhotoInMemoryDevice(magicalCamera.getPhoto(),"myPhotoName","myDirectoryName", MagicalCamera.JPEG, true);
    

    如果(路径!= null) Toast.makeText(MainActivity.this, "图片保存在设备中,请查看路径:" + path, Toast.LENGTH_SHORT).show(); 别的 Toast.makeText(MainActivity.this, "抱歉你的照片没有写在 devide,请联系 f***7593@gmail 并说出这个错误", Toast.LENGTH_SHORT).show();

更多详情请参考以上链接

【讨论】:

【参考方案5】:

    在您的布局中创建一个按钮(单击此按钮将打开一个对话框,您可以在其中选择是选择相机还是画廊)。

    现在在其类中初始化按钮:

    - onCreate 之前:

    Button btu;

    - onCreate 内部:

    btu = (Button) findViewById(R.id.BtUp);

    方法调用相机和图库

- onCreate 启动前

int CAMERA_REQUEST = 1;

- 方法调用摄像头

public void callCamera() 
    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    cameraIntent.putExtra("crop", "true");
    cameraIntent.putExtra("aspectX", 0);
    cameraIntent.putExtra("aspectY", 0);
    cameraIntent.putExtra("outputX", 200);
    cameraIntent.putExtra("outputY", 150);
    startActivityForResult(cameraIntent, CAMERA_REQUEST);

- 方法调用库

public void callGallery() 
    Intent intent = new Intent(Intent.ACTION_PICK,
                               MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(intent,0);

    创建一个方法来显示 AlertDialog,它似乎可以选择:

    public void showAlertDialog(Context context) 
    this.context = context;
    final String items[] = getString(R.string.TextTakeCam), getString(R.string.TextTakeGal);
    
    AlertDialog.Builder ab = new AlertDialog.Builder(MainActivity.this);
    ab.setTitle(getString(R.string.TextTitleDia));
    AlertDialog.Builder builder = ab.setItems(items, new DialogInterface.OnClickListener() 
        public void onClick(DialogInterface d, int choice) 
            if (choice == 0) 
                callCamera();
             else if (choice == 1) 
                image.setVisibility(View.INVISIBLE);
                callGallery();
            
        );
    ab.show();
    

    在按钮中调用 AlertDialog

    btu.setOnClickListener(new View.OnClickListener() 
    @Override
    public void onClick(View v) 
        String title = getString(R.string.TextUp);
        String msg = getString(R.string.TextUp2);
        showAlertDialog2(MainActivity.this,title,msg,true);
        //maneger.UpdateC(edname.getText().toString(),edfoto.getText().toString(),ednum. getText().toString());
        
    );
    

AndroidManifest.xml 内部

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

【讨论】:

以上是关于android 3d画廊(转)的主要内容,如果未能解决你的问题,请参考以下文章

android画廊怎样做出超炫效果

android画廊怎样做出超炫效果

android点击画廊某张图片,目的使整个画廊放大,所点击的图片仍放中间,这个效果怎么设置

android 卡片画廊效果及RecycleView、ViewPager、ScrollView之前的冲突解决

在android中广告轮播是怎么做的

基于Unity3d 引擎的Android游戏优化(转)