0

透かしのような写真編集機能をやっています。

ユーザーは画像 A を選択します。画像が選択された後、ユーザーは別の画像 B を選択して画像 A の上に配置し、画像 A が背面で静止している間に画像 B を移動できます。

画像 B の配置が完了したら、ユーザーは両方の画像を 1 つに結合し、それを 1つの画像として保存できます。

画像 B 関数の移動は完了しましたが、実際に 2 つの画像を結合する方法がわかりません。

編集 1: カメラまたはギャラリーから取得し、B と A の 2 つの画像を結合して、SD カードに保存します。

編集2: これは、画像Bをビュー内で移動させるために行ったことです。今必要なのは、画像 b をメイン画像 (背景にある) に接続し、SD カードとして保存することだけです。イメージビューとそのカスタム位置 (イメージ B) の両方を実際に統合し、SD カードに保存できるビットマップを作成する方法はありますか。

private ImageView img_additionalImage;

float x, y = 0.0f;
boolean isImageMoving = false;

img_additionalImage = (ImageView) findViewById(R.id.img_additionalImage);
        img_additionalImage.setOnTouchListener(new OnTouchListener()
    {

        @SuppressLint("NewApi")
        @Override
        public boolean onTouch(View v, MotionEvent event)
        {
            switch (event.getAction())
            {
                case MotionEvent.ACTION_DOWN:
                    isImageMoving = true;
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (isImageMoving)
                    {
                        x = event.getRawX() - img_additionalImage.getWidth() / 2;
                        y = event.getRawY() - img_additionalImage.getHeight() / 2;
                        img_additionalImage.setX(x);
                        img_additionalImage.setY(y);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    isImageMoving = false;
                    break;
            }
            return true;
        }
    });

編集 3: これは、これを呼び出したときに nullpointer を与えるコードです。

主な活動

CombineImages combineImages = new CombineImages(MainActivity.this);
img_additionalImage = (ImageView) findViewById(R.id.img_additionalImage);
combineImages.combine(img_additionalImage);

CombineImages クラスはあなたが提供したものです。

12-31 20:54:33.470: E/AndroidRuntime(6330): FATAL EXCEPTION: main
12-31 20:54:33.470: E/AndroidRuntime(6330): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.photosharingtest2/com.example.photosharingtest2.MainActivity}: java.lang.NullPointerException
12-31 20:54:33.470: E/AndroidRuntime(6330):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2024)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at android.app.ActivityThread.access$600(ActivityThread.java:140)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at android.os.Looper.loop(Looper.java:137)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at android.app.ActivityThread.main(ActivityThread.java:4898)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at java.lang.reflect.Method.invokeNative(Native Method)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at java.lang.reflect.Method.invoke(Method.java:511)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at dalvik.system.NativeStart.main(Native Method)
12-31 20:54:33.470: E/AndroidRuntime(6330): Caused by: java.lang.NullPointerException
12-31 20:54:33.470: E/AndroidRuntime(6330):     at android.content.ContextWrapper.getResources(ContextWrapper.java:81)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at android.view.View.<init>(View.java:3314)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at com.example.photosharingtest2.CombineImages.<init>(CombineImages.java:27)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at com.example.photosharingtest2.MainActivity.<init>(MainActivity.java:39)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at java.lang.Class.newInstanceImpl(Native Method)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at java.lang.Class.newInstance(Class.java:1319)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at android.app.Instrumentation.newActivity(Instrumentation.java:1057)
12-31 20:54:33.470: E/AndroidRuntime(6330):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2015)
12-31 20:54:33.470: E/AndroidRuntime(6330):     ... 11 more
4

3 に答える 3

2

レンダリングした画像をキャプチャする最も簡単な方法は、ImageViewasのレイアウトsetDrawingCacheEnabledtrueにすることです。これにより、imageview の画像をキャプチャして に変換し、SD カードにBitmap保存できます。

ImageView imageView = (ImageView)findViewById(R.id.imageview_here);
imageView.setDrawingCacheEnabled(true);
imageView.buildDrawingCache(true);
Bitmap bitmap = Bitmap.createBitmap(imageView.getDrawingCache());
imageView.setDrawingCacheEnabled(false);

以下の画像をsdcardに保存します。

           String root = Environment.getExternalStorageDirectory().toString();
        File newDir = new File(root + "/saved_images");
        newDir.mkdirs();
        Random gen = new Random();
        int n = 10000;
        n = gen.nextInt(n);
        String fotoname = "photo-" + n + ".jpg";
        File file = new File(newDir, fotoname);
        String s = file.getAbsolutePath();
        System.err.print("******************" + s);
        if (file.exists())
            file.delete();
        try {
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
            out.flush();
            out.close();
        } catch (Exception e) { }
                     try {
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
            out.flush();
            out.close();
        } catch (Exception e) {

        }
于 2013-12-31T09:00:01.303 に答える
1

私はあなたのために簡単なことを書きました。コンバインメソッドを持ったキャンバスバッファ付きのビューです。バッファに画像を描画して表示します。アプリケーションには 2 つCombineImagesのビューと、ユーザーが現在移動しているビューが必要です。彼がその位置を設定したら、CombineImages.combine を呼び出してその画像をビューに追加し、その画像を削除するよりも、別の画像を追加する準備が整いました。

現在、すべての画像を左上に配置しています。コードを少し編集して、コスチュームの位置で機能させる必要があります。

CombineImages.combineまた、UI スレッド以外から呼び出しても安全であることにも注意してください。

    public class CombineImages extends View{

            private Bitmap buffer;
            private Canvas canvas;
            private Matrix matrix = new Matrix();

            public CombineImages(Context context, AttributeSet attrs) {
                super(context, attrs);
            }

            public CombineImages(Context context) {
                super(context);
            }

            public void combine(ImageView imageView){
                Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
                combine(bitmap);
            }

            public void combine(Bitmap bitmap) {
                updateBuffer(bitmap);
                draw(canvas);
                postInvalidate();
            }

            @Override
            protected void onDraw(Canvas canvas) {
                super.onDraw(canvas);
                canvas.drawBitmap(buffer, matrix , null);
            }

            private void updateBuffer(Bitmap bitmap) {
                if(buffer == null){
                    createBuffer(bitmap);
                }
                else{
                    if(bitmap.getWidth() > buffer.getWidth() || bitmap.getHeight() > buffer.getHeight()){
                        Bitmap oldBuffer = buffer;
                        createBuffer(bitmap);
                        drawBitmnapToBuffer(oldBuffer);
                        oldBuffer.recycle();
                    }
                    drawBitmnapToBuffer(bitmap);
                }

                getLayoutParams().height = buffer.getHeight();
                getLayoutParams().width = buffer.getWidth();                
            }

            private void drawBitmnapToBuffer(Bitmap bitmap) {
                canvas.save();
                // add your translation logic here using canvas.translate(dx, dy); 
                canvas.drawBitmap(bitmap, matrix, null);
                canvas.restore();
            }

            private void createBuffer(Bitmap bitmap) {
                buffer = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
                canvas = new Canvas(buffer);
            }
        }
于 2013-12-31T09:27:06.257 に答える
0

RealtiveLayout または LinearLayout を使用している場合は、この方法でそのビューをキャプチャできます..

view.setDrawingCacheEnabled(true);
Bitmap b = view.getDrawingCache();
b.compress(CompressFormat.JPEG, 95, new FileOutputStream("/some/location/image.jpg"));

ビューはあなたのビューです。95 は JPG 圧縮の品質です。そして、ファイル出力ストリームはまさにそれです。

于 2013-12-31T09:21:38.323 に答える