【问题标题】:how to overlay one bitmap to another and save on sdcard如何将一个位图叠加到另一个位图并保存在 sdcard 上
【发布时间】:2013-03-23 08:47:49
【问题描述】:

我正在开发图像编辑器,我正在使用自定义类来绘制位图,这是我的代码..

private void settingBitmapToDraw() {
    // TODO Auto-generated method stub

    resultBitmap=Bitmap.createScaledBitmap(resultBitmap, WIDTH, HEIGHT, true);
    Matrix matrix=new Matrix();
    matrix.setRotate(TO_DEGREE);
    tempBitmap=Bitmap.createBitmap(resultBitmap, 0, 0, WIDTH, HEIGHT, 
    matrix,  true);

    bitmap=Bitmap.createBitmap(WIDTH, HEIGHT, tempBitmap.getConfig());
    canvas=new Canvas(bitmap);

    invalidate();

}

protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);

    canvas.drawBitmap(tempBitmap, xAxis, yAxis, paint);

    if(overlayBitmap!=null)
    {
        canvas.drawBitmap(overlayBitmap, xAxis+50, yAxis+50, paint);
    }
}

public void overlayImage() {
    // TODO Auto-generated method stub

    ImageProcessing.SAVE_STATUS=false;
    overlayBitmap=BitmapFactory.decodeResource(getResources(),
            R.drawable.add_image);
    invalidate();

}

位图在画布上绘制,但在保存时会另存为黑色图像。 这是我保存的位图代码...

    try {
FileOutputStream fos=new FileOutputStream(file);
updatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
    SAVE_STATUS=true;
saveDialog.dismiss();
} catch (FileNotFoundException e) {
  // TODO Auto-generated catch block
    e.printStackTrace();
}

更新的位图由'bitmap'初始化

public Bitmap getUpdatedImage() {
    // TODO Auto-generated method stub
    //width=2048 height=1232

    Bitmap updatedBitmap=Bitmap.createScaledBitmap(bitmap, 
            orgWidth, orgHeight, true);
    return updatedBitmap;

}

///////////// 我的 ImageProcessing.java 类有代码...

if(!SAVE_STATUS)
{
updatedBitmap=ip_DrawingClass.getUpdatedImage();
if(updatedBitmap!=null)
{
    file=new File(file_root);
    saveDialog.show();
}
else
{
    Toast.makeText(ImageProcessing.this,
            "file can't saved...",  Toast.LENGTH_SHORT).show();
}
}   

saveDialog 有保存按钮,保存上面写的保存图像的代码。

////////////////////////


    @Override
public boolean onTouchEvent(MotionEvent event) {
    // TODO Auto-generated method stub

    float xAxis,yAxis;

    switch(event.getAction()&MotionEvent.ACTION_MASK)
    {
    case MotionEvent.ACTION_DOWN:
        MODE="DRAG";
        startX=event.getX();
        startY=event.getY();
        if(ImageProcessing.drawLineStatus)
            path.moveTo(startX, startY);
        break;
    case MotionEvent.ACTION_POINTER_DOWN:
        MODE="ZOOM";
        oldDist=this.findDistanceXY(event);
        break;
    case MotionEvent.ACTION_MOVE:
        if(MODE=="ZOOM")
        {
            newDist=findDistanceXY(event);
            if(newDist>oldDist)
            {
                this.applyZooming("plus");
            }
            else
            {
                this.applyZooming("minus");
            }
            oldDist=newDist;
        }
        else if(MODE=="DRAG")
        {
            xAxis=event.getX();
            yAxis=event.getY();
            if(!lock_status)
            {
                this.translateImage(xAxis,yAxis,startX,startY);
            }
            else
            {
               this.translateTextOnBitmap
                                         (xAxis,yAxis,startX,startY);
            }

            if(ImageProcessing.drawLineStatus)
            {
                path.lineTo(xAxis, yAxis);
                this.drawLinesOnBitmap();
            }
            else
                draw_line=false;
        }
        break;
    case MotionEvent.ACTION_POINTER_UP:
        MODE="DRAG";
        this.setZoomBoxXY();
        break;
    case MotionEvent.ACTION_UP:
        this.set_XY_Axis();
        break;
    }

    return true;
}

图片在这里翻译..

 public void translateImage(float x, float y, float startX, float startY) {
// TODO Auto-generated method stub

    if((startX>=imageAtX&&startX<=(imageAtX+imageW))&&
                (startY>=imageAtY&&startY<=(imageAtY+imageH)))
    {
        if(imagePortionSelected||crop_status)
        {
            if((startX>=selectorAtX&&startX<=(selectorAtX+ZOOM))
                               &&(startY>=selectorAtY&&startY<=(selectorAtY+ZOOM)))
            {
                left=(int)(x-(startX-selectorAtX));
                top=(int)(y-(startY-selectorAtY));
                right=left+ZOOM;
                bottom=top+ZOOM;
                checkForValidityOfPara();
            }
            rect.set(left, top, right, bottom);
        }
        else
        {
            xAxis=x-(startX-imageAtX);
            yAxis=y-(startY-imageAtY); 
        }
    }

    invalidate();
}

【问题讨论】:

  • 也在这里分享“保存位图”代码。
  • 感谢您的回复..我已经添加了我的保存位图代码请看..

标签: android bitmap android-canvas


【解决方案1】:

要合并 2 个位图,请使用以下方法

public Bitmap combineImages(Bitmap frame, Bitmap image) {

    Bitmap cs = null;
    Bitmap rs = null;

    rs = Bitmap.createScaledBitmap(frame, image.getWidth(),
            image.getHeight(), true);

    cs = Bitmap.createBitmap(rs.getWidth(), rs.getHeight(),
            Bitmap.Config.RGB_565);

    Canvas comboImage = new Canvas(cs);

    comboImage.drawBitmap(image, 0, 0, null);
    comboImage.drawBitmap(rs, 0, 0, null);

    if (rs != null) {
        rs.recycle();
        rs = null;
    }
    Runtime.getRuntime().gc();

    return cs;
}

为了保存组合图像,请在任何你想要的地方使用下面的代码......

 Bitmap outBmp = combineImages(bmp1, bmp2);

    imageFileFolder = new File(Environment.getExternalStorageDirectory(),
            "FOLDER_PHOTOS");
    imageFileFolder.mkdir();
    FileOutputStream out1 = null;

    imageFileName = new File(imageFileFolder, "file_name.jpg");

        out1 = new FileOutputStream(imageFileName);
        outBmp.compress(Bitmap.CompressFormat.JPEG, 100, out1);
        out1.flush();
        out1.close();

【讨论】:

    【解决方案2】:

    您没有在更新的位图上绘图。在保存之前在更新的位图上绘制第一个位图和覆盖位图。将您的 getUpdatedImage() 更改为此-

    protected void getUpdatedImage() {
    
    int width = tempBitmap.getWidth();
    int height  = tempBitmap.getHeight();
    Bitmap updatedBitmap=Bitmap.createScaledBitmap(bitmap, 
            width, height, true);
    Canvas canvas  = new Canvas(updatedBitmap);
    
    canvas.drawBitmap(tempBitmap, xAxis, yAxis, paint);
    
    if(overlayBitmap!=null)
    {
        canvas.drawBitmap(overlayBitmap, xAxis+50, yAxis+50, paint);
    }
    
    //now save the updated bitmap
    return updatedBitmap;
    }
    

    【讨论】:

    • 您可能做错了什么。您可以在问题中发布更多代码以及操作流程吗?
    • 谢谢兄弟...它可以工作,但还有另一个问题,画布的剩余空间用位图文件绘制为黑色,有什么解决方案..?
    • 我很高兴它有效。对于黑色空间问题,检查 updatedBitmap 的高度和宽度是否与 tempBitmapoverlayBitmap 相同
    • 不,它不一样..// 那时我将位图缩放为其原始大小,当它第一次加载时我缩小了。
    • 您应该创建 updateBitmap 大小为 tempBitmapoverlayBitmap 中较小的那个,然后在画布上绘制。我已经更新了我的答案以反映这一点。
    【解决方案3】:

    要保存位图试试这个...-

     public void savebitmap(final Bitmap bitmap)
    {
        AlertDialog.Builder alert = new AlertDialog.Builder(Work.this);
    alert.setMessage("File name :"); //get file name from user
        input = new EditText(Work.this);
        input.setLayoutParams(new LayoutParams(100,50));
        alert.setView(input);
        alert.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                String _mNameValue = input.getText().toString();
                try
                {
                    File fn=new File("/sdcard/"+_mNameValue+".png");
                    FileOutputStream out=new FileOutputStream(fn);
                    Toast.makeText(getApplicationContext(), "In Save",Toast.LENGTH_SHORT).show();
                    bitmap.compress(Bitmap.CompressFormat.PNG, 90,out);
                    out.flush();
                    out.close();    
                    Toast.makeText(getApplicationContext(), "File is Saved in   "+fn, Toast.LENGTH_SHORT).show();
                }
                catch(Exception e){
                    e.printStackTrace();        
                }
            }
        });
        alert.show();
    }
    

    这在我这里工作得很好。

    ontouch 事件-

        paint = new Paint();
                        paint.setAntiAlias(true);
                        paint.setColor(getResources().getColor(R.color.Yellow)) ;
                        paint.setAlpha(opacity);
    
                            _ImageView.setAdjustViewBounds(true);
                              _ImageView.setImageBitmap(_MutableImage1);
                              canvas1 = new Canvas(_MutableImage1);
                              canvas1.drawRect(event.getX()-10,event.getY()-10,event.getX()+10,event.getY()+10, paint);
                              bitmap1=_MutableImage1.copy(Bitmap.Config.ARGB_4444,false);
    

    【讨论】:

    • 谢谢兄弟..我已经完成了这个请检查我更新的问题..谢谢
    • 首先要绘制,您必须创建原始位图 mutable.so 您可以在该位图上绘制。再次完成绘制后使该位图不可变,如 '_MutableImage2=bitmap.copy(Bitmap.Config. ARGB_4444,真); // 对于可变和不可变位图,使其为 false bitmapm=_MutableImage2.copy(Bitmap.Config.ARGB_4444,false);'这将解决您的问题
    • 我已经完成了这个..它在 m 地方工作。首先做图像可变位图 _MutableImage2=orignal_bitmap.copy(Bitmap.Config.ARGB_4444, true);然后将其传递给draw mathod,再次执行操作后使其不可变 bitmapm=_MutableImage2.copy(Bitmap.Config.ARGB_4444,false) 然后保存bitmapm
    • 我已经试过了。查看我的代码,如果你发现其中有任何问题,谢谢
    • 我已经更新了我的代码。有在图像上绘制矩形的示例代码
    【解决方案4】:

    使用此代码。您必须将绘图布局保存为图像。希望下面的代码对你有所帮助。

    Bitmap bm;
        DrawingLayout.setDrawingCacheEnabled(true);
        bm = DrawingLayout.getDrawingCache();
    
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();
        //String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/drawn_image";
        String path = getFilesDir() .getAbsolutePath();
        boolean exists = (new File(path)).exists();
        /*if (!exists) {
            new File(path).mkdirs();
        }*/
        OutputStream outStream = null;
        File file = new File(path, "drawn_image" + ".PNG");
        try {
            outStream = new FileOutputStream(file);
            bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);            
            outStream.flush();
            outStream.close();               
    
        } catch (FileNotFoundException e) {
    
            e.printStackTrace();
    
        } catch (IOException e) {
    
            e.printStackTrace();
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-11
      • 1970-01-01
      • 2014-07-28
      • 2011-07-05
      • 1970-01-01
      • 2012-09-02
      • 2011-09-06
      • 1970-01-01
      相关资源
      最近更新 更多