我正在做一个有点像水印的照片编辑功能。
用户选择图像A.在选择图像之后,用户可以选择另一图像B填充在图像A的顶部,并且他们可以移动图像B,而图像A在后面仍然是静止的。 / p>
完成图像B的放置后,用户可以将两个图像合并为一个并将其另存为单个图像。
我完成了图像B功能的运动,但我不确定如何将两个图像实际组合在一起。
编辑1: 我希望它们可以从相机或画廊中取出然后合并两张图像,B在A上并将其保存到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的代码。
MainActivity
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
答案 0 :(得分:2)
捕获已渲染图像的最简单方法是将ImageView
的布局设为setDrawingCacheEnabled
为 true ,这样您就可以捕获图像将imageview转换为Bitmap
并将其保存到SD卡中。
ImageView imageView = (ImageView)findViewById(R.id.imageview_here);
imageView.setDrawingCacheEnabled(true);
imageView.buildDrawingCache(true);
Bitmap bitmap = Bitmap.createBitmap(imageView.getDrawingCache());
imageView.setDrawingCacheEnabled(false);
将图片如下所示保存到SD卡中。
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) {
}
答案 1 :(得分:1)
我为你写了一些简单的事情。它是一个带有画布缓冲区的视图,它具有组合方法。它在缓冲区上绘制图像并显示它们。您的应用需要有两个视图CombineImages
和您的用户当前正在移动的视图。一旦他设置了它的位置,你就可以调用Combine说明书将该图像添加到视图中,而不是删除该图像,现在就可以添加另一个图像。
目前我将所有图片放在左上角,你应该稍微编辑我的代码,使其与服装位置一起工作。
另请注意,不能从UI-Thread
调用CombineImages.combine
是安全的
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);
}
}
答案 2 :(得分:0)
如果您使用RealtiveLayout或LinearLayout,则可以通过这种方式捕获该视图。
view.setDrawingCacheEnabled(true);
Bitmap b = view.getDrawingCache();
b.compress(CompressFormat.JPEG, 95, new FileOutputStream("/some/location/image.jpg"));
视图是您的视图。 95是JPG压缩的质量。文件输出流就是那个。