Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fixes #499] Add new feature - Converting PDF pages to images #505

Merged
merged 13 commits into from
Oct 17, 2018
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import swati4star.createpdf.fragment.HomeFragment;
import swati4star.createpdf.fragment.ImageToPdfFragment;
import swati4star.createpdf.fragment.MergeFilesFragment;
import swati4star.createpdf.fragment.PdfToImageFragment;
import swati4star.createpdf.fragment.QrBarcodeScanFragment;
import swati4star.createpdf.fragment.RemovePagesFragment;
import swati4star.createpdf.fragment.SettingsFragment;
Expand Down Expand Up @@ -307,6 +308,9 @@ public boolean onNavigationItemSelected(@NonNull MenuItem item) {
case R.id.nav_extract_images:
fragment = new ExtractImagesFragment();
break;
case R.id.nav_pdf_to_images:
fragment = new PdfToImageFragment();
break;
case R.id.nav_remove_pages:
fragment = new RemovePagesFragment();
bundle.putString(BUNDLE_DATA, REMOVE_PAGES);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class HomeFragment extends Fragment implements View.OnClickListener {
MyCardView rearrangePages;
@BindView(R.id.extract_images)
MyCardView extractImages;
@BindView(R.id.pdf_to_images)
MyCardView mPdfToImages;
@BindView(R.id.add_password)
MyCardView addPassword;
@BindView(R.id.remove_password)
Expand All @@ -72,6 +74,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
removePages.setOnClickListener(this);
rearrangePages.setOnClickListener(this);
extractImages.setOnClickListener(this);
mPdfToImages.setOnClickListener(this);
addPassword.setOnClickListener(this);
removePassword.setOnClickListener(this);
rotatePdf.setOnClickListener(this);
Expand Down Expand Up @@ -135,6 +138,10 @@ public void onClick(View v) {
fragment = new ExtractImagesFragment();
setNavigationViewSelection(10);
break;
case R.id.pdf_to_images:
fragment = new PdfToImageFragment();
setNavigationViewSelection(11);
break;
case R.id.remove_pages:
fragment = new RemovePagesFragment();
bundle.putString(BUNDLE_DATA, REMOVE_PAGES);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
package swati4star.createpdf.fragment;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomSheetBehavior;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.afollestad.materialdialogs.MaterialDialog;
import com.airbnb.lottie.LottieAnimationView;
import com.dd.morphingbutton.MorphingButton;

import java.io.File;
import java.util.ArrayList;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import swati4star.createpdf.R;
import swati4star.createpdf.activity.ImagesPreviewActivity;
import swati4star.createpdf.adapter.ExtractImagesAdapter;
import swati4star.createpdf.adapter.MergeFilesAdapter;
import swati4star.createpdf.interfaces.BottomSheetPopulate;
import swati4star.createpdf.interfaces.ExtractImagesListener;
import swati4star.createpdf.util.BottomSheetCallback;
import swati4star.createpdf.util.BottomSheetUtils;
import swati4star.createpdf.util.FileUtils;
import swati4star.createpdf.util.MorphButtonUtility;
import swati4star.createpdf.util.PdfToImages;
import swati4star.createpdf.util.ViewFilesDividerItemDecoration;

import static android.app.Activity.RESULT_OK;
import static swati4star.createpdf.util.DialogUtils.createAnimationDialog;
import static swati4star.createpdf.util.FileUriUtils.getFilePath;
import static swati4star.createpdf.util.StringUtils.showSnackbar;

public class PdfToImageFragment extends Fragment implements BottomSheetPopulate, MergeFilesAdapter.OnClickListener,
ExtractImagesListener, ExtractImagesAdapter.OnFileItemClickedListener {

private static final int INTENT_REQUEST_PICKFILE_CODE = 10;
private Activity mActivity;
private String mPath;
private Uri mUri;
private MorphButtonUtility mMorphButtonUtility;
private FileUtils mFileUtils;
private BottomSheetBehavior mSheetBehavior;
private BottomSheetUtils mBottomSheetUtils;
private ArrayList<String> mOutputFilePaths;
private MaterialDialog mMaterialDialog;

@BindView(R.id.lottie_progress)
LottieAnimationView mLottieProgress;
@BindView(R.id.bottom_sheet)
LinearLayout mLayoutBottomSheet;
@BindView(R.id.upArrow)
ImageView mUpArrow;
@BindView(R.id.selectFile)
MorphingButton mSelectFileButton;
@BindView(R.id.createImages)
MorphingButton mCreateImagesButton;
@BindView(R.id.created_images)
RecyclerView mCreatedImages;
@BindView(R.id.pdfToImagesText)
TextView mCreateImagesSuccessText;
@BindView(R.id.options)
LinearLayout options;
@BindView(R.id.layout)
RelativeLayout mLayout;
@BindView(R.id.recyclerViewFiles)
RecyclerView mRecyclerViewFiles;

/**
* inflates the layout for the fragment
* @param inflater reference to inflater object
* @param container parent for the inflated view
* @param savedInstanceState bundle with saved data, if any
* @return inflated view
*/
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_pdf_to_image, container, false);
ButterKnife.bind(this, rootView);
mSheetBehavior = BottomSheetBehavior.from(mLayoutBottomSheet);
mSheetBehavior.setBottomSheetCallback(new BottomSheetCallback(mUpArrow, isAdded()));
mLottieProgress.setVisibility(View.VISIBLE);
mBottomSheetUtils.populateBottomSheetWithPDFs(this);
resetView();
return rootView;
}

/**
* called when user chooses to share generated images
*/
@OnClick(R.id.shareImages)
void onShareFilesClick() {
if (mOutputFilePaths != null) {
ArrayList<File> fileArrayList = new ArrayList<>();
for (String path : mOutputFilePaths) {
fileArrayList.add(new File(path));
}
mFileUtils.shareMultipleFiles(fileArrayList);
}
}

/**
* called on click of bottom sheet
*/
@OnClick(R.id.viewFiles)
void onViewFilesClick() {
mBottomSheetUtils.showHideSheet(mSheetBehavior);
}

/**
* called when user chooses to view generated images
*/
@OnClick(R.id.viewImages)
void onViewImagesClicked() {
mActivity.startActivity(ImagesPreviewActivity.getStartIntent(mActivity, mOutputFilePaths));
}

/**
* invoked when user chooses to select a pdf file
* initiates an intent to pick a pdf file
*/
@OnClick(R.id.selectFile)
public void showFileChooser() {
startActivityForResult(mFileUtils.getFileChooser(),
INTENT_REQUEST_PICKFILE_CODE);
}

/**
* receives intent response for selecting a pdf file
*/
public void onActivityResult(int requestCode, int resultCode, Intent data) throws NullPointerException {
if (data == null || resultCode != RESULT_OK || data.getData() == null)
return;
if (requestCode == INTENT_REQUEST_PICKFILE_CODE) {
mUri = data.getData();
setTextAndActivateButtons(getFilePath(data.getData()));
}
}

/**
* invokes generation of images for pdf pages in the background
*/
@OnClick(R.id.createImages)
public void parse() {
new PdfToImages(mPath, mUri, this).execute();
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
mActivity = (Activity) context;
mMorphButtonUtility = new MorphButtonUtility(mActivity);
mFileUtils = new FileUtils(mActivity);
mBottomSheetUtils = new BottomSheetUtils(mActivity);
}

/**
* handles choosing a file from bottom sheet list
* @param path path of the file on the device
*/
@Override
public void onItemClick(String path) {
mUri = null;
mSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
setTextAndActivateButtons(path);
}

/**
* handles text and button states
* @param path path of the file on the device
*/
private void setTextAndActivateButtons(String path) {
mCreatedImages.setVisibility(View.GONE);
options.setVisibility(View.GONE);
mCreateImagesSuccessText.setVisibility(View.GONE);
mPath = path;
mMorphButtonUtility.setTextAndActivateButtons(path,
mSelectFileButton, mCreateImagesButton);
}

/**
* handles opening a generated image for the given pdf
* @param path path of the file on the device
*/
@Override
public void onFileItemClick(String path) {
mFileUtils.openImage(path);
}

/**
* initializes interactive views
*/
@Override
public void resetView() {
mPath = null;
mMorphButtonUtility.initializeButton(mSelectFileButton, mCreateImagesButton);
}

/**
* displays progress indicator
*/
@Override
public void extractionStarted() {
mMaterialDialog = createAnimationDialog(mActivity);
mMaterialDialog.show();
}

/**
* updates recycler view list items based with the generated images
* @param imageCount number of generated images
* @param outputFilePaths path for each generated image
*/
@Override
public void updateView(int imageCount, ArrayList<String> outputFilePaths) {

mMaterialDialog.dismiss();
resetView();
if (imageCount == 0) {
showSnackbar(mActivity, R.string.extract_images_failed);
return;
}

String text = String.format(mActivity.getString(R.string.create_images_success), imageCount);
showSnackbar(mActivity, text);
mCreateImagesSuccessText.setVisibility(View.VISIBLE);
options.setVisibility(View.VISIBLE);
mOutputFilePaths = outputFilePaths;
ExtractImagesAdapter extractImagesAdapter = new ExtractImagesAdapter(mActivity, outputFilePaths, this);
// init recycler view for displaying generated image list
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(mActivity);
mCreateImagesSuccessText.setText(text);
mCreatedImages.setVisibility(View.VISIBLE);
mCreatedImages.setLayoutManager(mLayoutManager);
// set up adapter
mCreatedImages.setAdapter(extractImagesAdapter);
mCreatedImages.addItemDecoration(new ViewFilesDividerItemDecoration(mActivity));
}

/**
* populates bottom sheet list with pdf files
* @param paths paths for pdf files on the device
*/
@Override
public void onPopulate(ArrayList<String> paths) {
if (paths == null || paths.size() == 0) {
mLayout.setVisibility(View.GONE);
} else {
// init recycler view for bottom sheet
mRecyclerViewFiles.setVisibility(View.VISIBLE);
MergeFilesAdapter mergeFilesAdapter = new MergeFilesAdapter(mActivity,
paths, this);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(mActivity);
mRecyclerViewFiles.setLayoutManager(mLayoutManager);
// set up adapter
mRecyclerViewFiles.setAdapter(mergeFilesAdapter);
mRecyclerViewFiles.addItemDecoration(new ViewFilesDividerItemDecoration(mActivity));
}
mLottieProgress.setVisibility(View.GONE);
}
}
2 changes: 1 addition & 1 deletion app/src/main/java/swati4star/createpdf/util/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ public static String getFileDirectoryPath(String path) {
* @param filename - name of the file
* @param finalBitmap - bitmap to save
*/
static String saveImage(String filename, Bitmap finalBitmap) {
public static String saveImage(String filename, Bitmap finalBitmap) {

if (checkIfBitmapIsWhite(finalBitmap))
return null;
Expand Down
Loading