Aufnehmen eines Bildes mit der Kamera und Senden an den Server in bytearray

Ich arbeite an einer Andorid-Anwendung, in der der Benutzer ein Bild aufnehmen und es dann zum Speichern an den Server senden soll. Jetzt sende ich das Bild als Byte-Array an den Server. Wenn ich versuche, das Byte-Array in einer Datei als PNG-Datei zu speichern und dann zu öffnen, meldet der Bildbetrachter, dass das PNG Fehler aufweist und nicht angezeigt werden kann. Die PNG-Dateigröße betrug 122 KB.

Wenn ich versucht habe, die Größe des Bildes mit der Scalr-Bibliothek zu ändern, kann die Bildquelle nicht null sein. Das direkte Speichern des Byte-Arrays führt zu einem beschädigten PNG. Wie soll ich die Datei richtig konvertieren und an den Server senden, damit es keine Fehler gibt? Hier ist der Code für die Kamera, die ich verwende und über die ich sie sende.

public class AddPhotoForUser extends DrawerLoader {

    private static final int CAMERA_PIC_REQUEST = 22;
    Button BtnSelectImage;
    private ImageView ImgPhoto;
    private static volatile Bitmap photo;
    private static volatile ByteArrayOutputStream stream = new ByteArrayOutputStream();

    final PersonServiceImpl personService = new PersonServiceImpl();

    private String[] navMenuTitles;
    private TypedArray navMenuIcons;

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

        navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
        navMenuIcons = getResources()
                .obtainTypedArray(R.array.nav_drawer_icons);

        set(navMenuTitles, navMenuIcons);

        Button uploadImageButton = (Button) findViewById(R.id.uploadUserImageButton);
        uploadImageButton.setVisibility(View.INVISIBLE);

        ImgPhoto = (ImageView) findViewById(R.id.userPhotoImageView);
        BtnSelectImage = (Button) findViewById(R.id.userPhotoButtonSelect);
        BtnSelectImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {

                    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);

                } catch (Exception e) {
                    Toast.makeText(getApplicationContext(), "Couldn't load photo", Toast.LENGTH_LONG).show();
                }
            }
        });

        uploadImageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!(v == null)) {
                    uploadImage();
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Intent intent = new Intent(AddPhotoForUser.this, RestaurantList.class);
                    startActivity(intent);
                    finish();

                }
            }
        });

    }

    @Override
    public void onBackPressed() {
        Intent intent = new Intent(AddPhotoForUser.this, Login.class);
        startActivity(intent);
        finish();
    }

    @Override
    public void onActivityResult(final int requestCode, int resultCode, Intent data) {
        try {
            switch (requestCode) {
                case CAMERA_PIC_REQUEST:
                    if (resultCode == RESULT_OK) {
                        try {
                            photo = (Bitmap) data.getExtras().get("data");
                            if (!(photo == null)) {
                                ImgPhoto.setImageBitmap(photo);
                                Button uploadImageButton = (Button) findViewById(R.id.uploadUserImageButton);
                                uploadImageButton.setVisibility(View.VISIBLE);

                            }
                        } catch (Exception e) {
                            Toast.makeText(this, "Couldn't load photo", Toast.LENGTH_LONG).show();
                        }
                    }
                    break;
                default:
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    private void uploadImage() {

        if (!(photo == null)) {
            photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] byteArray = stream.toByteArray();
            personService.addUserProfilePhoto(byteArray);
        }

    }
}

Hier ist der serverseitige Code, um das Image auf der Festplatte zu speichern:

 @Override
    public Boolean updateProfilePhoto(byte[] photo) {
        Person person = getCurrentlyAuthenticatedPerson();
        try{
           InputStream in = new ByteArrayInputStream(photo);
            BufferedImage image = ImageIO.read(in);
            image = Scalr.resize(image, Scalr.Method.QUALITY, 100, 100);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(image, "png", baos);
            baos.flush();
            File file = new File(userImagePath);
            if (file.exists() && file.isDirectory()) {
                OutputStream outputStream = new FileOutputStream(new File(userImagePath + person.getUserId()+".png"));
                outputStream.write(baos.toByteArray());
                outputStream.close();
            } else {
                File file1 = new File(userImagePath+person.getUserId()+".png");
                if (file1.exists()) {
                    try {
                        OutputStream outputStream = new FileOutputStream(file1);
                        outputStream.write(baos.toByteArray());
                        outputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();

                    }
                } else {
                   boolean result = file1.createNewFile();
                    System.out.println("Result of file1 creation is "+result);
                    OutputStream outputStream = new FileOutputStream(file1);
                    outputStream.write(baos.toByteArray());
                    outputStream.close();
                }
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

Wenn ich die Scalr-Bibliothek nicht verwende, gibt es keine Fehler, aber es ist eine beschädigte Datei. Hier ist das Scalr-Fehlerprotokoll:

java.lang.IllegalArgumentException: src cannot be null
    at org.imgscalr.Scalr.resize(Scalr.java:1564)
    at org.imgscalr.Scalr.resize(Scalr.java:1415)
    at com.journaldev.spring.service.PersonServiceImpl.updateProfilePhoto(PersonServiceImpl.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at com.sun.proxy.$Proxy51.updateProfilePhoto(Unknown Source)
    at com.journaldev.spring.Controller.PersonController.addProfilePhotoForUser(PersonController.java:100)

Jede Hilfe wäre nett. Danke vielmals. : -)

Aktueller Code

public class AddPhotoForUser extends DrawerLoader {


    Button BtnSelectImage;
    private ImageView ImgPhoto;

    private static volatile ByteArrayOutputStream stream = new ByteArrayOutputStream();

    final PersonServiceImpl personService = new PersonServiceImpl();

    private String[] navMenuTitles;
    private TypedArray navMenuIcons;

    private static final int CAMERA_PHOTO = 111;
    private Uri imageToUploadUri;

    Bitmap reducedSizeBitmap;

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

        navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
        navMenuIcons = getResources()
                .obtainTypedArray(R.array.nav_drawer_icons);

        set(navMenuTitles, navMenuIcons);

        Button uploadImageButton = (Button) findViewById(R.id.uploadUserImageButton);
        uploadImageButton.setVisibility(View.INVISIBLE);

        ImgPhoto = (ImageView) findViewById(R.id.userPhotoImageView);
        BtnSelectImage = (Button) findViewById(R.id.userPhotoButtonSelect);
        BtnSelectImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {

                    captureCameraImage();
                } catch (Exception e) {
                    Toast.makeText(getApplicationContext(), "Couldn't load photo", Toast.LENGTH_LONG).show();
                }
            }
        });

        uploadImageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!(v == null)) {
                    uploadImage();
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Intent intent = new Intent(AddPhotoForUser.this, RestaurantList.class);
                    startActivity(intent);
                    finish();

                }
            }
        });

    }

    private Bitmap getBitmap(String path) {

        Uri uri = Uri.fromFile(new File(path));
        InputStream in = null;
        try {
            final int IMAGE_MAX_SIZE = 12000000; // 12MP
            in = getContentResolver().openInputStream(uri);

            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(in, null, o);
            in.close();


            int scale = 1;
            while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) >
                    IMAGE_MAX_SIZE) {
                scale++;
            }
            Log.d("", "scale = " + scale + ", orig-width: " + o.outWidth + ", orig-height: " + o.outHeight);

            Bitmap b = null;
            in = getContentResolver().openInputStream(uri);
            if (scale > 1) {
                scale--;
                // scale to max possible inSampleSize that still yields an image
                // larger than target
                o = new BitmapFactory.Options();
                o.inSampleSize = scale;
                b = BitmapFactory.decodeStream(in, null, o);

                // resize to desired dimensions
                int height = b.getHeight();
                int width = b.getWidth();
                Log.d("", "1th scale operation dimenions - width: " + width + ", height: " + height);

                double y = Math.sqrt(IMAGE_MAX_SIZE
                        / (((double) width) / height));
                double x = (y / height) * width;

                Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x,
                        (int) y, true);
                b.recycle();
                b = scaledBitmap;
                System.gc();
            } else {
                b = BitmapFactory.decodeStream(in);
            }
            in.close();

            Log.d("", "bitmap size - width: " + b.getWidth() + ", height: " +
                    b.getHeight());
            return b;
        } catch (IOException e) {
            Log.e("", e.getMessage(), e);
            return null;
        }
    }

    private void captureCameraImage() {
        Intent chooserIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File f = new File(Environment.getExternalStorageDirectory(), "POST_IMAGE.jpg");
        chooserIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
        imageToUploadUri = Uri.fromFile(f);
        startActivityForResult(chooserIntent, CAMERA_PHOTO);
    }

    @Override
    public void onBackPressed() {
        Intent intent = new Intent(AddPhotoForUser.this, Login.class);
        startActivity(intent);
        finish();
    }

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

        if (requestCode == CAMERA_PHOTO && resultCode == Activity.RESULT_OK) {
            if(imageToUploadUri != null){
                Uri selectedImage = imageToUploadUri;
                getContentResolver().notifyChange(selectedImage, null);
                reducedSizeBitmap = getBitmap(imageToUploadUri.getPath());
                if(reducedSizeBitmap != null){
                    ImgPhoto.setImageBitmap(reducedSizeBitmap);
                    Button uploadImageButton = (Button) findViewById(R.id.uploadUserImageButton);
                    uploadImageButton.setVisibility(View.VISIBLE);
                }else{
                    Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show();
                }
            }else{
                Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show();
            }
        }

    }

    private void uploadImage() {
        if(!(reducedSizeBitmap == null)){
            reducedSizeBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] byteArray = stream.toByteArray();
            this.personService.addUserProfilePhoto(byteArray);
        }
    }
}

Antworten auf die Frage(4)

Ihre Antwort auf die Frage