美文网首页
Android建筑图像过滤器,如Instagram(2)

Android建筑图像过滤器,如Instagram(2)

作者: ListenToCode | 来源:发表于2018-10-10 15:59 被阅读30次

    14。打开FiltersListFragment.java并进行如下所示的修改。这里

    FilterPack.getFilterPack()提供库中可用过滤器的列表。

    >prepareThumbnail()方法中,过滤器被填充,并且每个缩略图项目都被添加到ThumbnailsManager以处理它们。处理后的缩略图将添加回thumbnailItemList,后者是RecyclerView的数据资源。

    >缩略图数据集准备就绪后,调用mAdapter.notifyDataSetChanged()来渲染列表。所有这些都是在后台线程中完成的,因为图像处理需要一段时间,我们不应该阻止主线程。

    >每当选择新过滤器时,FiltersListFragmentListener接口都会为主活动提供回调方法。

    MainActivity中将对所选图像过滤器的实际处理进行处理。

    FiltersListFragment.java

    packageinfo.androidhive.imagefilters;

    importandroid.graphics.Bitmap;

    importandroid.os.Bundle;

    importandroid.support.v4.app.Fragment;

    importandroid.support.v7.widget.DefaultItemAnimator;

    importandroid.support.v7.widget.LinearLayoutManager;

    importandroid.support.v7.widget.RecyclerView;

    importandroid.util.Log;

    importandroid.util.TypedValue;

    importandroid.view.LayoutInflater;

    importandroid.view.View;

    importandroid.view.ViewGroup;

    importcom.zomato.photofilters.FilterPack;

    importcom.zomato.photofilters.imageprocessors.Filter;

    importcom.zomato.photofilters.utils.ThumbnailItem;

    importcom.zomato.photofilters.utils.ThumbnailsManager;

    importjava.util.ArrayList;

    importjava.util.HashMap;

    importjava.util.List;

    importjava.util.Map;

    importbutterknife.BindView;

    importbutterknife.ButterKnife;

    importinfo.androidhive.imagefilters.utils.BitmapUtils;

    importinfo.androidhive.imagefilters.utils.SpacesItemDecoration;

    publicclassFiltersListFragment extendsFragment implementsThumbnailsAdapter.ThumbnailsAdapterListener {

        @BindView(R.id.recycler_view)

        RecyclerView recyclerView;

        ThumbnailsAdapter mAdapter;

        List thumbnailItemList;

        FiltersListFragmentListener listener;

        publicvoidsetListener(FiltersListFragmentListener listener) {

            this.listener = listener;

        }

        publicFiltersListFragment() {

            // Required empty public constructor

        }

        @Override

        publicvoidonCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

        }

        @Override

        publicView onCreateView(LayoutInflater inflater, ViewGroup container,

                                 Bundle savedInstanceState) {

            // Inflate the layout for this fragment

            View view = inflater.inflate(R.layout.fragment_filters_list, container, false);

            ButterKnife.bind(this, view);

            thumbnailItemList = newArrayList<>();

            mAdapter = newThumbnailsAdapter(getActivity(), thumbnailItemList, this);

            RecyclerView.LayoutManager mLayoutManager = newLinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);

            recyclerView.setLayoutManager(mLayoutManager);

            recyclerView.setItemAnimator(newDefaultItemAnimator());

            intspace = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,

                    getResources().getDisplayMetrics());

            recyclerView.addItemDecoration(newSpacesItemDecoration(space));

            recyclerView.setAdapter(mAdapter);

            prepareThumbnail(null);

            returnview;

        }

        /**

         * Renders thumbnails in horizontal list

         * loads default image from Assets if passed param is null

         *

         * @param bitmap

         */

        publicvoidprepareThumbnail(finalBitmap bitmap) {

            Runnable r = newRunnable() {

                publicvoidrun() {

                    Bitmap thumbImage;

                    if(bitmap == null) {

                        thumbImage = BitmapUtils.getBitmapFromAssets(getActivity(), MainActivity.IMAGE_NAME, 100, 100);

                    } else{

                        thumbImage = Bitmap.createScaledBitmap(bitmap, 100, 100, false);

                    }

                    if(thumbImage == null)

                        return;

                    ThumbnailsManager.clearThumbs();

                    thumbnailItemList.clear();

                    // add normal bitmap first

                    ThumbnailItem thumbnailItem = newThumbnailItem();

                    thumbnailItem.image = thumbImage;

                    thumbnailItem.filterName = getString(R.string.filter_normal);

                    ThumbnailsManager.addThumb(thumbnailItem);

                    List filters = FilterPack.getFilterPack(getActivity());

                    for(Filter filter : filters) {

                        ThumbnailItem tI = newThumbnailItem();

                        tI.image = thumbImage;

                        tI.filter = filter;

                        tI.filterName = filter.getName();

                        ThumbnailsManager.addThumb(tI);

                    }

                    thumbnailItemList.addAll(ThumbnailsManager.processThumbs(getActivity()));

                    getActivity().runOnUiThread(newRunnable() {

                        @Override

                        publicvoidrun() {

                            mAdapter.notifyDataSetChanged();

                        }

                    });

                }

            };

            newThread(r).start();

        }

        @Override

        publicvoidonFilterSelected(Filter filter) {

            if(listener != null)

                listener.onFilterSelected(filter);

        }

        publicinterfaceFiltersListFragmentListener {

            voidonFilterSelected(Filter filter);

        }

    }

    7.添加图像编辑控件片段

    现在我们将添加图像控件片段来控制亮度对比度饱和度

    15。按照与上一步相同的步骤再创建一个名为EditImageFragment.java的片段。打开此片段fragment_edit_image.xml的布局文件,并执行如下修改。

    在这个布局中,我们将添加三个SeekBar小部件来控制图像亮度,对比度和饱和度。

    fragment_edit_image.xml

    http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:gravity="center_vertical"

        android:orientation="vertical"

        android:paddingLeft="@dimen/margin_horizontal"

        android:paddingRight="@dimen/margin_horizontal"

        tools:context="info.androidhive.imagefilters.EditImageFragment">

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:orientation="horizontal"

            android:paddingBottom="@dimen/padding_10"

            android:paddingTop="@dimen/padding_10">

                android:layout_width="@dimen/lbl_edit_image_control"

                android:layout_height="wrap_content"

                android:text="@string/lbl_brightness"/>

                android:id="@+id/seekbar_brightness"

                android:layout_width="0dp"

                android:layout_height="wrap_content"

                android:layout_weight="1"/>

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:orientation="horizontal"

            android:paddingBottom="@dimen/padding_10"

            android:paddingTop="@dimen/padding_10">

                android:layout_width="@dimen/lbl_edit_image_control"

                android:layout_height="wrap_content"

                android:text="@string/lbl_contrast"/>

                android:id="@+id/seekbar_contrast"

                android:layout_width="0dp"

                android:layout_height="wrap_content"

                android:layout_weight="1"/>

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:orientation="horizontal"

            android:paddingBottom="@dimen/padding_10"

            android:paddingTop="@dimen/padding_10">

                android:layout_width="@dimen/lbl_edit_image_control"

                android:layout_height="wrap_content"

                android:text="@string/lbl_saturation"/>

                android:id="@+id/seekbar_saturation"

                android:layout_width="0dp"

                android:layout_height="wrap_content"

                android:layout_weight="1"/>

    16。打开EditImageFragment.java并进行如下修改。

    >onCreateView方法中,Seekbar小部件使用初始值和最大值进行初始化。对于亮度,值可以在-100 / +100之间。在对比度饱和度采取浮动值。

    >每当Seekbar值发生更改时,EditImageFragmentListener接口都会提供回调方法。

    >在回调时,MainActivity再次处理亮度对比度饱和度

    EditImageFragment.java

    packageinfo.androidhive.imagefilters;

    importandroid.os.Bundle;

    importandroid.support.v4.app.Fragment;

    importandroid.util.Log;

    importandroid.view.LayoutInflater;

    importandroid.view.View;

    importandroid.view.ViewGroup;

    importandroid.widget.SeekBar;

    importbutterknife.BindView;

    importbutterknife.ButterKnife;

    publicclassEditImageFragment extendsFragment implementsSeekBar.OnSeekBarChangeListener {

        privateEditImageFragmentListener listener;

        @BindView(R.id.seekbar_brightness)

        SeekBar seekBarBrightness;

        @BindView(R.id.seekbar_contrast)

        SeekBar seekBarContrast;

        @BindView(R.id.seekbar_saturation)

        SeekBar seekBarSaturation;

        publicvoidsetListener(EditImageFragmentListener listener) {

            this.listener = listener;

        }

        publicEditImageFragment() {

            // Required empty public constructor

        }

        @Override

        publicvoidonCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

        }

        @Override

        publicView onCreateView(LayoutInflater inflater, ViewGroup container,

                                 Bundle savedInstanceState) {

            View view = inflater.inflate(R.layout.fragment_edit_image, container, false);

            ButterKnife.bind(this, view);

            // keeping brightness value b/w -100 / +100

            seekBarBrightness.setMax(200);

            seekBarBrightness.setProgress(100);

            // keeping contrast value b/w 1.0 - 3.0

            seekBarContrast.setMax(20);

            seekBarContrast.setProgress(0);

            // keeping saturation value b/w 0.0 - 3.0

            seekBarSaturation.setMax(30);

            seekBarSaturation.setProgress(10);

            seekBarBrightness.setOnSeekBarChangeListener(this);

            seekBarContrast.setOnSeekBarChangeListener(this);

            seekBarSaturation.setOnSeekBarChangeListener(this);

            returnview;

        }

        @Override

        publicvoidonProgressChanged(SeekBar seekBar, intprogress, booleanb) {

            if(listener != null) {

                if(seekBar.getId() == R.id.seekbar_brightness) {

                    // brightness values are b/w -100 to +100

                    listener.onBrightnessChanged(progress - 100);

                }

                if(seekBar.getId() == R.id.seekbar_contrast) {

                    // converting int value to float

                    // contrast values are b/w 1.0f - 3.0f

                    // progress = progress > 10 ? progress : 10;

                    progress += 10;

                    floatfloatVal = .10f * progress;

                    listener.onContrastChanged(floatVal);

                }

                if(seekBar.getId() == R.id.seekbar_saturation) {

                    // converting int value to float

                    // saturation values are b/w 0.0f - 3.0f

                    floatfloatVal = .10f * progress;

                    listener.onSaturationChanged(floatVal);

                }

            }

        }

        @Override

        publicvoidonStartTrackingTouch(SeekBar seekBar) {

            if(listener != null)

                listener.onEditStarted();

        }

        @Override

        publicvoidonStopTrackingTouch(SeekBar seekBar) {

            if(listener != null)

                listener.onEditCompleted();

        }

        publicvoidresetControls() {

            seekBarBrightness.setProgress(100);

            seekBarContrast.setProgress(0);

            seekBarSaturation.setProgress(10);

        }

        publicinterfaceEditImageFragmentListener {

            voidonBrightnessChanged(intbrightness);

            voidonSaturationChanged(floatsaturation);

            voidonContrastChanged(floatcontrast);

            voidonEditStarted();

            voidonEditCompleted();

        }

    }

    8.实现主界面(组合片段)

    现在我们准备好了片段,让我们看看如何将它们组合起来以实现我们的最终输出。

    17。打开主活动activity_main.xmlcontent_main.xml以及NonSwipeableViewPagerTabLayout的布局文件。

    activity_main.xml中

    http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        tools:context="info.androidhive.imagefilters.MainActivity">

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:theme="@style/AppTheme.AppBarOverlay">

                android:id="@+id/toolbar"

                android:layout_width="match_parent"

                android:layout_height="?attr/actionBarSize"

                android:background="@android:color/white"

                app:popupTheme="@style/AppTheme.PopupOverlay"/>

    content_main.xml

    http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:background="@android:color/white"

        android:orientation="vertical"

        app:layout_behavior="@string/appbar_scrolling_view_behavior"

        tools:context="info.androidhive.imagefilters.MainActivity"

        tools:showIn="@layout/activity_main">

            android:id="@+id/image_preview"

            android:layout_width="match_parent"

            android:layout_height="360dp"

            android:scaleType="centerCrop"/>

            android:id="@+id/viewpager"

            android:layout_width="match_parent"

            android:layout_height="120dp"

            android:layout_above="@+id/tabs"

            android:layout_below="@+id/image_preview"

            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

            android:id="@+id/tabs"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_alignParentBottom="true"

            app:tabGravity="fill"

            app:tabMode="fixed"/>

    18。打开MainActivity.java并执行如下所示的更改。

    >调用System.loadLibrary(“NativeImageProcessor”)来初始化本机库。

    FiltersListFragmentEditImageFragments加到ViewPager在setupViewPager()方法。

    onFilterSelected()当在被选择的过滤器将被称为FiltersListFragment。处理选定的过滤器,并显示最终图像imagePreview

    onBrightnessChanged()onSaturationChanged()onContrastChanged()方法将在EditImageFragments中的Seekbar值更改时调用。

    >从工具栏中选择“保存”选项后,最终图像将保存到图库。

    MainActivity.java

    packageinfo.androidhive.imagefilters;

    importandroid.Manifest;

    importandroid.content.Intent;

    importandroid.graphics.Bitmap;

    importandroid.net.Uri;

    importandroid.os.Bundle;

    importandroid.support.design.widget.CoordinatorLayout;

    importandroid.support.design.widget.Snackbar;

    importandroid.support.design.widget.TabLayout;

    importandroid.support.v4.app.Fragment;

    importandroid.support.v4.app.FragmentManager;

    importandroid.support.v4.app.FragmentPagerAdapter;

    importandroid.support.v4.view.ViewPager;

    importandroid.support.v7.app.AppCompatActivity;

    importandroid.support.v7.widget.Toolbar;

    importandroid.text.TextUtils;

    importandroid.util.Log;

    importandroid.view.Menu;

    importandroid.view.MenuItem;

    importandroid.view.View;

    importandroid.widget.ImageView;

    importandroid.widget.Toast;

    importcom.karumi.dexter.Dexter;

    importcom.karumi.dexter.MultiplePermissionsReport;

    importcom.karumi.dexter.PermissionToken;

    importcom.karumi.dexter.listener.PermissionRequest;

    importcom.karumi.dexter.listener.multi.MultiplePermissionsListener;

    importcom.zomato.photofilters.imageprocessors.Filter;

    importcom.zomato.photofilters.imageprocessors.subfilters.BrightnessSubFilter;

    importcom.zomato.photofilters.imageprocessors.subfilters.ContrastSubFilter;

    importcom.zomato.photofilters.imageprocessors.subfilters.SaturationSubfilter;

    importjava.util.ArrayList;

    importjava.util.List;

    importbutterknife.BindView;

    importbutterknife.ButterKnife;

    importinfo.androidhive.imagefilters.utils.BitmapUtils;

    publicclassMainActivity extendsAppCompatActivity implementsFiltersListFragment.FiltersListFragmentListener, EditImageFragment.EditImageFragmentListener {

        privatestaticfinalString TAG = MainActivity.class.getSimpleName();

        publicstaticfinalString IMAGE_NAME = "dog.jpg";

        publicstaticfinalintSELECT_GALLERY_IMAGE = 101;

        @BindView(R.id.image_preview)

        ImageView imagePreview;

        @BindView(R.id.tabs)

        TabLayout tabLayout;

        @BindView(R.id.viewpager)

        ViewPager viewPager;

        @BindView(R.id.coordinator_layout)

        CoordinatorLayout coordinatorLayout;

        Bitmap originalImage;

        // to backup image with filter applied

        Bitmap filteredImage;

        // the final image after applying

        // brightness, saturation, contrast

        Bitmap finalImage;

        FiltersListFragment filtersListFragment;

        EditImageFragment editImageFragment;

        // modified image values

        intbrightnessFinal = 0;

        floatsaturationFinal = 1.0f;

        floatcontrastFinal = 1.0f;

        // load native image filters library

        static{

            System.loadLibrary("NativeImageProcessor");

        }

        @Override

        protectedvoidonCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_main);

            ButterKnife.bind(this);

            Toolbar toolbar = findViewById(R.id.toolbar);

            setSupportActionBar(toolbar);

            getSupportActionBar().setDisplayHomeAsUpEnabled(true);

            getSupportActionBar().setTitle(getString(R.string.activity_title_main));

            loadImage();

            setupViewPager(viewPager);

            tabLayout.setupWithViewPager(viewPager);

        }

        privatevoidsetupViewPager(ViewPager viewPager) {

            ViewPagerAdapter adapter = newViewPagerAdapter(getSupportFragmentManager());

            // adding filter list fragment

            filtersListFragment = newFiltersListFragment();

            filtersListFragment.setListener(this);

            // adding edit image fragment

            editImageFragment = newEditImageFragment();

            editImageFragment.setListener(this);

            adapter.addFragment(filtersListFragment, getString(R.string.tab_filters));

            adapter.addFragment(editImageFragment, getString(R.string.tab_edit));

            viewPager.setAdapter(adapter);

        }

        @Override

        publicvoidonFilterSelected(Filter filter) {

            // reset image controls

            resetControls();

            // applying the selected filter

            filteredImage = originalImage.copy(Bitmap.Config.ARGB_8888, true);

            // preview filtered image

            imagePreview.setImageBitmap(filter.processFilter(filteredImage));

            finalImage = filteredImage.copy(Bitmap.Config.ARGB_8888, true);

        }

        @Override

        publicvoidonBrightnessChanged(finalintbrightness) {

            brightnessFinal = brightness;

            Filter myFilter = newFilter();

            myFilter.addSubFilter(newBrightnessSubFilter(brightness));

            imagePreview.setImageBitmap(myFilter.processFilter(finalImage.copy(Bitmap.Config.ARGB_8888, true)));

        }

        @Override

        publicvoidonSaturationChanged(finalfloatsaturation) {

            saturationFinal = saturation;

            Filter myFilter = newFilter();

            myFilter.addSubFilter(newSaturationSubfilter(saturation));

            imagePreview.setImageBitmap(myFilter.processFilter(finalImage.copy(Bitmap.Config.ARGB_8888, true)));

        }

        @Override

        publicvoidonContrastChanged(finalfloatcontrast) {

            contrastFinal = contrast;

            Filter myFilter = newFilter();

            myFilter.addSubFilter(newContrastSubFilter(contrast));

            imagePreview.setImageBitmap(myFilter.processFilter(finalImage.copy(Bitmap.Config.ARGB_8888, true)));

        }

        @Override

        publicvoidonEditStarted() {

        }

        @Override

        publicvoidonEditCompleted() {

            // once the editing is done i.e seekbar is drag is completed,

            // apply the values on to filtered image

            finalBitmap bitmap = filteredImage.copy(Bitmap.Config.ARGB_8888, true);

            Filter myFilter = newFilter();

            myFilter.addSubFilter(newBrightnessSubFilter(brightnessFinal));

            myFilter.addSubFilter(newContrastSubFilter(contrastFinal));

            myFilter.addSubFilter(newSaturationSubfilter(saturationFinal));

            finalImage = myFilter.processFilter(bitmap);

        }

        /**

         * Resets image edit controls to normal when new filter

         * is selected

         */

        privatevoidresetControls() {

            if(editImageFragment != null) {

                editImageFragment.resetControls();

            }

            brightnessFinal = 0;

            saturationFinal = 1.0f;

            contrastFinal = 1.0f;

        }

        classViewPagerAdapter extendsFragmentPagerAdapter {

            privatefinalList mFragmentList = newArrayList<>();

            privatefinalList mFragmentTitleList = newArrayList<>();

            publicViewPagerAdapter(FragmentManager manager) {

                super(manager);

            }

            @Override

            publicFragment getItem(intposition) {

                returnmFragmentList.get(position);

            }

            @Override

            publicintgetCount() {

                returnmFragmentList.size();

            }

            publicvoidaddFragment(Fragment fragment, String title) {

                mFragmentList.add(fragment);

                mFragmentTitleList.add(title);

            }

            @Override

            publicCharSequence getPageTitle(intposition) {

                returnmFragmentTitleList.get(position);

            }

        }

        // load the default image from assets on app launch

        privatevoidloadImage() {

            originalImage = BitmapUtils.getBitmapFromAssets(this, IMAGE_NAME, 300, 300);

            filteredImage = originalImage.copy(Bitmap.Config.ARGB_8888, true);

            finalImage = originalImage.copy(Bitmap.Config.ARGB_8888, true);

            imagePreview.setImageBitmap(originalImage);

        }

        @Override

        publicbooleanonCreateOptionsMenu(Menu menu) {

            getMenuInflater().inflate(R.menu.menu_main, menu);

            returntrue;

        }

        @Override

        publicbooleanonOptionsItemSelected(MenuItem item) {

            intid = item.getItemId();

            if(id == R.id.action_open) {

                openImageFromGallery();

                returntrue;

            }

            if(id == R.id.action_save) {

                saveImageToGallery();

                returntrue;

            }

            returnsuper.onOptionsItemSelected(item);

        }

        @Override

        protectedvoidonActivityResult(intrequestCode, intresultCode, Intent data) {

            if(resultCode == RESULT_OK && requestCode == SELECT_GALLERY_IMAGE) {

                Bitmap bitmap = BitmapUtils.getBitmapFromGallery(this, data.getData(), 800, 800);

                // clear bitmap memory

                originalImage.recycle();

                finalImage.recycle();

                finalImage.recycle();

                originalImage = bitmap.copy(Bitmap.Config.ARGB_8888, true);

                filteredImage = originalImage.copy(Bitmap.Config.ARGB_8888, true);

                finalImage = originalImage.copy(Bitmap.Config.ARGB_8888, true);

                imagePreview.setImageBitmap(originalImage);

                bitmap.recycle();

                // render selected image thumbnails

                filtersListFragment.prepareThumbnail(originalImage);

            }

        }

        privatevoidopenImageFromGallery() {

            Dexter.withActivity(this).withPermissions(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)

                    .withListener(newMultiplePermissionsListener() {

                        @Override

                        publicvoidonPermissionsChecked(MultiplePermissionsReport report) {

                            if(report.areAllPermissionsGranted()) {

                                Intent intent = newIntent(Intent.ACTION_PICK);

                                intent.setType("image/*");

                                startActivityForResult(intent, SELECT_GALLERY_IMAGE);

                            } else{

                                Toast.makeText(getApplicationContext(), "Permissions are not granted!", Toast.LENGTH_SHORT).show();

                            }

                        }

                        @Override

                        publicvoidonPermissionRationaleShouldBeShown(List permissions, PermissionToken token) {

                            token.continuePermissionRequest();

                        }

                    }).check();

        }

        /*

        * saves image to camera gallery

        * */

        privatevoidsaveImageToGallery() {

            Dexter.withActivity(this).withPermissions(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)

                    .withListener(newMultiplePermissionsListener() {

                        @Override

                        publicvoidonPermissionsChecked(MultiplePermissionsReport report) {

                            if(report.areAllPermissionsGranted()) {

                                finalString path = BitmapUtils.insertImage(getContentResolver(), finalImage, System.currentTimeMillis() + "_profile.jpg", null);

                                if(!TextUtils.isEmpty(path)) {

                                    Snackbar snackbar = Snackbar

                                            .make(coordinatorLayout, "Image saved to gallery!", Snackbar.LENGTH_LONG)

                                            .setAction("OPEN", newView.OnClickListener() {

                                                @Override

                                                publicvoidonClick(View view) {

                                                    openImage(path);

                                                }

                                            });

                                    snackbar.show();

                                } else{

                                    Snackbar snackbar = Snackbar

                                            .make(coordinatorLayout, "Unable to save image!", Snackbar.LENGTH_LONG);

                                    snackbar.show();

                                }

                            } else{

                                Toast.makeText(getApplicationContext(), "Permissions are not granted!", Toast.LENGTH_SHORT).show();

                            }

                        }

                        @Override

                        publicvoidonPermissionRationaleShouldBeShown(List permissions, PermissionToken token) {

                            token.continuePermissionRequest();

                        }

                    }).check();

        }

        // opening image in default image viewer app

        privatevoidopenImage(String path) {

            Intent intent = newIntent();

            intent.setAction(Intent.ACTION_VIEW);

            intent.setDataAndType(Uri.parse(path), "image/*");

            startActivity(intent);

        }

    }

    运行应用程序并测试一次。您应该看到文章中显示的漂亮界面。您可以从列表中应用不同的滤镜,并可以控制亮度,饱和度和对比度。

    已知的问题

    1。当前图像控件更改图像控件时,亮度,对比度和饱和度不平滑。这是由于SeekBar值更改时递归处理/复制位图。改进必须在原生水平上完成。

    2。过滤器不像Instagram那么好。在库的下一个版本中,我将尝试即兴创建过滤器。

    3。过滤器不适合所有类型的图像。例如:具有白色背景的图像看起来与不同的滤镜几乎相似。

    相关文章

      网友评论

          本文标题:Android建筑图像过滤器,如Instagram(2)

          本文链接:https://www.haomeiwen.com/subject/iaapaftx.html