嗨,我试图从动画视图生成gif
简而言之,我在FrameLayout中有了ImageView和动画视图,现在我想生成主FrameLayout的gif,最低sdk级别19。getDrawingCache位图并将它们按顺序排列成gif可能会导致内存越界问题。
当我点击“开始录制”时,我想要特定视图的gif或视频。
首先,您需要实现这些库:
implementation 'com.blankj:utilcodex:1.30.6'
implementation 'com.waynejo:androidndkgif:0.3.3'
implementation 'com.jiang.android.observablescheduler:schedule:1.0.1'
ImageUtils
,PathUtils
…)java.util.concurrent
替换AsyncTask
类XML:我试图做和你一样的事情:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/viewToBeRecorded"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:background="@android:color/holo_green_light"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:text="View To Be Recorded"
android:textStyle="bold" />
</RelativeLayout>
<Button
android:id="@+id/changeBg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change Background"
android:textStyle="bold" />
<Button
android:id="@+id/startRecord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Record"
android:textStyle="bold" />
<Button
android:id="@+id/stopRecord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:text="Stop Record"
android:textStyle="bold" />
</LinearLayout>
爪哇岛:
public class MainActivity extends AppCompatActivity {
private Button changeBg, startRecord, stopRecord;
private RelativeLayout viewToBeRecorded;
private boolean isRecording = false;
private GifEncoder mGifEncoder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeViews();
startRecord.setOnClickListener(v -> {
isRecording = true;
ToastUtils.showShort("Start recording...");
startRecord.setEnabled(false);
stopRecord.setEnabled(true);
generateGIF();
});
stopRecord.setOnClickListener(v -> {
isRecording = false;
ToastUtils.showShort("Stop recording...");
startRecord.setEnabled(true);
stopRecord.setEnabled(false);
});
changeBg.setOnClickListener(v -> {
Random rnd = new Random();
int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
viewToBeRecorded.setBackgroundColor(color);
});
}
private void generateGIF() {
JObservable.create((JObservable.OnSubscribe<String>) mSubscriber -> {
try {
File storageDir = new File(PathUtils.getExternalPicturesPath() + "/GIFs");
FileUtils.createOrExistsDir(storageDir);
File gifFile = new File(storageDir, "GIF" + System.currentTimeMillis() + ".gif");
String outputPath = gifFile.getAbsolutePath();
Bitmap firstFrame = ImageUtils.view2Bitmap(viewToBeRecorded);
try {
mGifEncoder.init(firstFrame.getWidth(), firstFrame.getHeight(), outputPath, GifEncoder.EncodingType.ENCODING_TYPE_SIMPLE_FAST);
while (isRecording) {
Bitmap frame = ImageUtils.view2Bitmap(viewToBeRecorded);
mGifEncoder.encodeFrame(frame, 100);
Thread.sleep(20);
}
mGifEncoder.close();
mSubscriber.notifyData(outputPath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (Exception e) {
mSubscriber.error(e);
}
}).workedOn(Schedules.background())
.subscribeOn(Schedules.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void notifyData(String outputPath) {
FileUtils.notifySystemToScan(outputPath);
ToastUtils.showShort("GIF saved!");
}
@Override
public void error(Throwable t) {
Log.e("View2GIF", "generateGIF throw error : " + t.getMessage());
}
});
}
private void initializeViews() {
viewToBeRecorded = findViewById(R.id.viewToBeRecorded);
changeBg = findViewById(R.id.changeBg);
stopRecord = findViewById(R.id.stopRecord);
startRecord = findViewById(R.id.startRecord);
mGifEncoder = new GifEncoder();
}
输出:
别忘了添加:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
并确保授予存储权限
6.2.3.FrameLayout FrameLayout(帧布局)将其下的子元素相互覆盖起来,就像一副扑克牌,只留一个显示在外面。它可以用于标签的实现,也可以作为以后要用的控件的临时存放地。
虽然使用GraphiQL效果很好,但我的老板要求我实现一个用户界面,用户可以通过诸如checkbox、map relationships之类的UI元素检查呈现给他们的元素,并获取数据,这样做将为用户生成GraphiQL输入,调用API并将结果返回给用户。 所以,基本上这涉及到两代人。从GraphQL模式生成用户界面,并从用户的选择生成GraphQL输入查询。 我搜索了一下,但没有找到任何工具已经做
问题内容: 是否有可能从byte []生成java.security.cert.X509Certificate? 问题答案: 当然。 证书对象可以由CertificateFactory的一个实例创建- 尤其是配置为创建X509证书的一个实例。可以这样创建: 然后,您需要向其传递一个包含证书字节的InputStream。这可以通过将字节数组包装在ByteArrayInputStream中来实现:
问题内容: 我正在尝试在给定私钥和已知曲线的情况下生成公钥。下面是我的代码: 但是,当我打电话给 我时:我得到了例外:(不是我的拼写错误) 我似乎在计算错误,但是我不确定错误在哪里。 谢谢您的帮助! 问题答案: 如果我未来的自己需要解决方案:
我是编程新手。我在使用GraphicalLayout,然后当我阅读xml文件时,我看到了FrameLayout。然后我搜索了一下,但找不到有用的东西。什么是FrameLayout?它做什么?