Как сделать графический редактор для андроид
Как создать фоторедактор?
Нужен совет как сделать фоторедактор? То есть нужны только функии добавить изображение, изменить.
Graphic — быстрый фоторедактор на Android
Graphic – быстрый фоторедактор для платформы Android, с помощью которого можно снимать и.
Как создать APK (android)
Узнал про jQuery Mobile, возник вопрос на который я не нашел ответа, как проект с файлами html +.
Как создать Android проект?
Подскажите новичку как создать новый проект в Eclipse на базе уже имеющегося.
Как создать платёж в программе Android?
Есть бесплатная программа, в ней много активити, программу скачивают, но показов рекламы почти нет.
Как создать повторяющиеся события на android >= 6
Всем здравствуйте. Насколько мне известно, начиная с Android 6.0, не предоставляется возможным.
Как создать приложения Android Xamarin
Добрый день, можете посоветовать литературу по созданию Android приложений? С чего нужно начать?
Как создать приложение для Android
Я хочу создать приложение для Android, и я C ++ новичка (я знаю, классы и т.д.), как я могу создать.
Create Photo Editor Application Android Studio
Create Photo Editor Application Android Studio – Here i will show how to make android Photo Editor App in Android Studio. In this photo editors covers all features like remove objects, join the photos, crop, paint, brush and more facilities will be there in the photo editor. This is open source project so you can publish this photo editor in Google play store, no Copyrights issues raised.
Want to read our popular post to make money Online. Follow below post to get more cash,
- Data Entry Jobs from home.
- View & Click Ads, Watching Videos Earn $1 per Day
Now a days most of school and college students used photo editor application for make a stylish pictures. There are more photo editors application will be there is play store. If you have license for upload the android application in google play store, just use this source code and publish from play store. You did not get any copyrights issues.
Create Photo Editor Application Android Studio
Let’s start to develop photo editor android application in android studio. First create new project choose Empty Activity after creating the project just open the default class of MainActivity.java class file and add the following code,
MainActivity.java
In this project we need more java classes to develop android photo editor application in android studio. Finally i give full source code of android photo editor application you can download from that. Because here spaces are not enough to explain all the java code that’s why i did’t explain.
Activity Layouts
Integrate the XML files with Java classes. Open the under path of res =>layout =>activity_main.xml file and add the following code below,
Still more XML files will be there in this project so you can download the android photo editor project below.
Как создать прототип мобильного приложения?
Прототип приложения, в отличие от дизайн-концепции, дает возможность выполнить основные действия, увидеть связи между элементами интерфейса и их разные состояния. В самых продвинутых прототипах можно протестировать почти весь функционал. Вместе с Моисеем Любарским, автором модуля по Figma для курсов Contented, в том числе для курса «UX/UI-дизайнер с нуля до PRO», разбираемся, из каких этапов состоит работа над прототипом и какие для этого есть инструменты.
Для чего нужен прототип?
UX/UI-дизайнер
с нуля до ПРО
Для тех, кто хочет попасть в IT без навыков программирования
Прототипы помогают креативным командам решить несколько задач:
Создать архитектуру мобильного приложения, чтобы разобраться с механикой работы элементов и оценить объем задания.
- Дизайнер и арт-директор понимают, над какими UX- и UI-задачами работать.
- Разработчики оценивают продукт с точки зрения технической реализации.
- Стейкхолдеры в целом оценивают продукт с точки зрения рынка.
Составить roadmap (дорожную карту) продукта, то есть визуализацию плана работы на временной линии. Весь дальнейший процесс работы опирается на созданный прототип, и основные задачи команды тоже распределяются на этой стадии.
Пример roadmap проекта в Jira. Источник
Согласовать цели и задачи с заказчиком, чтобы утвердить объем работы и застраховать команду от неожиданных требований. Прототип становится частью ТЗ, и если заказчик просит добавить в приложение новый функционал, который не был утвержден, то обсуждается дополнительная оплата работы.
Создание прототипа состоит из трех основных этапов, на каждом из которых прорабатывается определенный аспект:
- Нулевой прототип — это эскиз, в котором быстро фиксируются идеи.
- Базовый прототип — это проработка основных механик работы приложения.
- Маркетинговый прототип — версия приложения с готовым дизайном.
Посмотрим, что происходит на каждом этапе.
Начало работы и эскиз
На этой стадии формируется идея, которую UX-дизайнер оформляет самостоятельно или вместе с командой. Эскиз нужен, чтобы перенести концепцию приложения из головы на бумагу и выделить важные этапы работы:
- Прописать логику взаимодействия пользователя с интерфейсом. С логикой дизайнеру обычно помогают UX-исследователь и продакт-менеджер. Они прописывают маршруты пользователей, то есть последовательность элементов, с которыми люди взаимодействуют, и экранов, на которые они переходят. Такие маршруты называют Customer Journey Map (CJM), и дизайнеру важно уметь с ними работать.
- Выбрать подходящие решения и механики взаимодействия. Для этого можно почитать дайджесты с трендами в сфере UX/UI, посмотреть уже существующие аналоги приложений, выписать идеи и UX-решения, которые могут быть удачными для нового проекта.
- Рассчитать примерное количество экранов. Например, в стандартном приложении для записи на услуги основными экранами будут welcome-экран со спецпредложениями, экран регистрации, главная страница, карточки услуг, календарь для выбора удобной даты, а также экран для подтверждения успешной регистрации и экран ошибки:
Для создания эскизов UX-дизайнеру даже не обязательно уметь рисовать от руки. Ему важнее понимать, как ведет себя пользователь, что для него будет удобно, а что нет. Эскизы можно рисовать от руки или даже в Paint; гораздо важнее делать понятные для себя и для остальной команды пометки. Или можно найти специальные скетчпады для UX/UI-дизайнеров:
SketchPad для эскизов мобильных приложений. Источник
Базовый прототип
Когда есть CJM и черновик экранов, можно переносить элементы в базовый прототип. Это самый важный этап, на котором прорабатываются все детали взаимодействия с пользователем. В нем может не быть дизайна, иллюстраций или иконок, но обязательно должны быть функционально важные элементы: кнопки, элементы навигации, всплывающие окна и формы регистрации. В отличие от эскиза, в базовом прототипе прорисовываются все экраны, и собирать такой прототип желательно в каком-нибудь инструменте:
Figma — это бесплатная онлайн-платформа, в которой можно создавать дизайн-проекты интерфейсов и прототипы, организовать совместную работу с командой в режиме реального времени и оставлять комментарии друг для друга прямо в макете. У Figma есть веб-версия, поэтому открывать проект и вносить в него комментарии могут в том числе заказчики, у которых не установлено десктопное приложение.
Рабочее пространство Figma
Adobe XD — это инструмент из пакета Adobe для создания интерфейсов веб-сайтов, приложений и других ресурсов. Его главное конкурентное преимущество — облачная интеграция с другими приложениями Creative Cloud: можно рисовать иллюстрации в Illustrator, создавать анимации в After Effects и редактировать фото в Photoshop.
Рабочее пространство Adobe XD. Источник
Sketch — это графический редактор для macOS, он не отстает по функциональности от Figma или Adobe XD, а дизайнеры отдают ему предпочтение за удобство использования. Но в отличие от других инструментов, он несовместим с другими оперативными системами, поэтому коллегам на Windows и Linux для совместной работы потребуются программы Avocode или Zeplin, которые позволят открывать файлы Sketch.
Рабочее пространство Sketch. Источник
Мобильные приложения должны решать проблему пользователя точно и оперативно, а для этого ему необходимо почти интуитивно ориентироваться в том, что и как работает. Поэтому Apple и Google, разработчики основных операционных систем для мобильных устройств, создали гайдлайны для разработчиков и UX/UI-дизайнеров, то есть набор рекомендаций и принципов разработки, которые помогают сделать приложения более единообразными.
Apple Human Interface Guidelines для iOS
В гайдлайне описаны основные принципы, отличающие iOS от других систем, а также содержатся рекомендации по размещению, форме и размерам элементов, например кнопок, верхнего бара или элементов управления действиями.
Google Material Design System для Android
Гайдлайн от Google содержит базовые принципы material-дизайна, рекомендации по разметке и композиции, выбору цветов и типографике.
Сориентироваться в правилах прототипирования мобильных приложений новичкам поможет Figma Community, где можно вбить в поисковой строке запрос prototype app и найти большое количество шаблонов разного уровня проработки:
Базовый прототип приложения. Источник
Работу лучше выстраивать в несколько этапов:
- Шаг 1. Сначала реализовать основной флоу (flow) — то есть главный маршрут пользователя, то действие, ради которого он открывает приложение: пройти урок, купить товар, заказать услугу.
- Шаг 2. Дальше можно добавлять сопутствующие экраны: блок «О нас», «Афиша» и другие возможности, которые дополняют приложение.
- Шаг 3. После создания экранов и размещения элементов управления создаются связи между элементами и переходы между экранами.
Базовый прототип может не соответствовать дизайн-концепции готового продукта, в нем делается упор на функциональность, поэтому вместо контента используются заглушки вместо иллюстраций, шаблонные тексты и заголовки Lorem Ipsum, чтобы показать шрифты, не имея реального текста.
Добавляем детали
Дизайн-концепция формируется заранее, еще на этапе исследования аудитории.
Дизайнер создает визуал, который должен решить две задачи:
- Поможет пользователю наиболее эффективно использовать приложение.
- Задаст нужную эстетику и вызовет эмоциональный отклик.
В базовый прототип интегрируется реальный контент: тексты, иллюстрации, иконки и так далее. На этой стадии проверяются выбранные дизайн-решения и то, работают ли они на заданные цели. Например, достаточно ли понятно графика иллюстрирует необходимые действия и вызывает ли она нужные эмоции.
Признаком хорошего тона в современном UX/UI-дизайне является максимально детальная проработка прототипа, то есть в нем прорисованы все элементы и не должно быть заглушек. В том числе можно:
- добавить анимацию: загрузка контента, переходы между экранами, всплывающие окна;
- указать все состояния элементов: как будет выглядеть иконка после добавления элемента в избранное или кнопка после нажатия;
- показать путь пользователя: как работают жесты, кнопки навигации и так далее.
В итоге получится примерно такой прототип, в котором продуманы все пользовательские сценарии от регистрации и восстановления пароля до выбора локации и анкетирования. Его уже можно передавать разработчикам, и на практике у них почти не возникает вопросов по механике работы приложения, если прототип детально проработан. Также на нем можно проводить исследования с реальными пользователями и собирать отзывы.
UX/UI-дизайнер с нуля до ПРО
Хотите делать мир удобнее и работать в IT-индустрии? Научитесь создавать интерфейсы приложений и сайтов без навыков программирования.
Похожие публикации:
- Где в вк купить голоса
- Как отменить подписку на патреон
- Как поменять тему клавиатуры на самсунг
- Как установить электронную почту на ноутбуке бесплатно
Графический редактор
В данной статье рассматривается создание простейшего графического редактора.
Наш редактор будет обладать самым минимальным функционалом: карандаш, кисть, ластик, рисование простейших фигур (линия, прямоугольник, овал), выбор цвета. Выбор цвета как из минимального набора в цветовой панели, так и из расширенного набора цветов.
Кроме того, можно будет загружать изображения, редактировать их и сохранять. Работа с изображениями в формате jpg и png.
import java.awt.*; import java.awt.geom.*; import java.awt.event.*; import java.io.*; import javax.swing.*; import javax.swing.event.*; import java.awt.image.*; import javax.imageio.*; import javax.swing.filechooser.FileFilter; public class ImageEdit < // Режим рисования int rezhim=0; int xPad; int xf; int yf; int yPad; int thickness; boolean pressed=false; // текущий цвет Color maincolor; MyFrame f; MyPanel japan; JButton colorbutton; JColorChooser tcc; // поверхность рисования BufferedImage imag; // если мы загружаем картинку boolean loading=false; String fileName; public ImageEdit() < f=new MyFrame("Графический редактор"); f.setSize(350,350); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); maincolor=Color.black; JMenuBar menuBar = new JMenuBar(); f.setJMenuBar(menuBar); menuBar.setBounds(0,0,350,30); JMenu fileMenu = new JMenu("Файл"); menuBar.add(fileMenu); Action loadAction = new AbstractAction("Загрузить") < public void actionPerformed(ActionEvent event) < JFileChooser jf= new JFileChooser(); int result = jf.showOpenDialog(null); if(result==JFileChooser.APPROVE_OPTION) < try < // при выборе изображения подстраиваем размеры формы // и панели под размеры данного изображения fileName = jf.getSelectedFile().getAbsolutePath(); File iF= new File(fileName); jf.addChoosableFileFilter(new TextFileFilter(".png")); jf.addChoosableFileFilter(new TextFileFilter(".jpg")); imag = ImageIO.read(iF); loading=true; f.setSize(imag.getWidth()+40, imag.getWidth()+80); japan.setSize(imag.getWidth(), imag.getWidth()); japan.repaint(); >catch (FileNotFoundException ex) < JOptionPane.showMessageDialog(f, "Такого файла не существует"); >catch (IOException ex) < JOptionPane.showMessageDialog(f, "Исключение ввода-вывода"); >catch (Exception ex) < >> > >; JMenuItem loadMenu = new JMenuItem(loadAction); fileMenu.add(loadMenu); Action saveAction = new AbstractAction("Сохранить") < public void actionPerformed(ActionEvent event) < try < JFileChooser jf= new JFileChooser(); // Создаем фильтры файлов TextFileFilter pngFilter = new TextFileFilter(".png"); TextFileFilter jpgFilter = new TextFileFilter(".jpg"); if(fileName==null) < // Добавляем фильтры jf.addChoosableFileFilter(pngFilter); jf.addChoosableFileFilter(jpgFilter); int result = jf.showSaveDialog(null); if(result==JFileChooser.APPROVE_OPTION) < fileName = jf.getSelectedFile().getAbsolutePath(); >> // Смотрим какой фильтр выбран if(jf.getFileFilter()==pngFilter) < ImageIO.write(imag, "png", new File(fileName+".png")); >else < ImageIO.write(imag, "jpeg", new File(fileName+".jpg")); >> catch(IOException ex) < JOptionPane.showMessageDialog(f, "Ошибка ввода-вывода"); >> >; JMenuItem saveMenu = new JMenuItem(saveAction); fileMenu.add(saveMenu); Action saveasAction = new AbstractAction("Сохранить как. ") < public void actionPerformed(ActionEvent event) < try < JFileChooser jf= new JFileChooser(); // Создаем фильтры для файлов TextFileFilter pngFilter = new TextFileFilter(".png"); TextFileFilter jpgFilter = new TextFileFilter(".jpg"); // Добавляем фильтры jf.addChoosableFileFilter(pngFilter); jf.addChoosableFileFilter(jpgFilter); int result = jf.showSaveDialog(null); if(result==JFileChooser.APPROVE_OPTION) < fileName = jf.getSelectedFile().getAbsolutePath(); >// Смотрим какой фильтр выбран if(jf.getFileFilter()==pngFilter) < ImageIO.write(imag, "png", new File(fileName+".png")); >else < ImageIO.write(imag, "jpeg", new File(fileName+".jpg")); >> catch(IOException ex) < JOptionPane.showMessageDialog(f, "Ошибка ввода-вывода"); >> >; JMenuItem saveasMenu = new JMenuItem(saveasAction); fileMenu.add(saveasMenu); japan = new MyPanel(); japan.setBounds(30,30,260,260); japan.setBackground(Color.white); japan.setOpaque(true); f.add(japan); JToolBar toolbar = new JToolBar("Toolbar", JToolBar.VERTICAL); JButton penbutton = new JButton(new ImageIcon("pen.png")); penbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < rezhim=0; >>); toolbar.add(penbutton); JButton brushbutton = new JButton(new ImageIcon("brush.png")); brushbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < rezhim=1; >>); toolbar.add(brushbutton); JButton lasticbutton = new JButton(new ImageIcon("lastic.png")); lasticbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < rezhim=2; >>); toolbar.add(lasticbutton); JButton textbutton = new JButton(new ImageIcon("text.png")); textbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < rezhim=3; >>); toolbar.add(textbutton); JButton linebutton = new JButton(new ImageIcon("line.png")); linebutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < rezhim=4; >>); toolbar.add(linebutton); JButton elipsbutton = new JButton(new ImageIcon("elips.png")); elipsbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < rezhim=5; >>); toolbar.add(elipsbutton); JButton rectbutton = new JButton(new ImageIcon("rect.png")); rectbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < rezhim=6; >>); toolbar.add(rectbutton); toolbar.setBounds(0, 0, 30, 300); f.add(toolbar); // Тулбар для кнопок JToolBar colorbar = new JToolBar("Colorbar", JToolBar.HORIZONTAL); colorbar.setBounds(30, 0, 260, 30); colorbutton = new JButton(); colorbutton.setBackground(maincolor); colorbutton.setBounds(15, 5, 20, 20); colorbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < ColorDialog coldi = new ColorDialog(f,"Выбор цвета"); coldi.setVisible(true); >>); colorbar.add(colorbutton); JButton redbutton = new JButton(); redbutton.setBackground(Color.red); redbutton.setBounds(40, 5, 15, 15); redbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < maincolor = Color.red; colorbutton.setBackground(maincolor); >>); colorbar.add(redbutton); JButton orangebutton = new JButton(); orangebutton.setBackground(Color.orange); orangebutton.setBounds(60, 5, 15, 15); orangebutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < maincolor = Color.orange; colorbutton.setBackground(maincolor); >>); colorbar.add(orangebutton); JButton yellowbutton = new JButton(); yellowbutton.setBackground(Color.yellow); yellowbutton.setBounds(80, 5, 15, 15); yellowbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < maincolor = Color.yellow; colorbutton.setBackground(maincolor); >>); colorbar.add(yellowbutton); JButton greenbutton = new JButton(); greenbutton.setBackground(Color.green); greenbutton.setBounds(100, 5, 15, 15); greenbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < maincolor = Color.green; colorbutton.setBackground(maincolor); >>); colorbar.add(greenbutton); JButton bluebutton = new JButton(); bluebutton.setBackground(Color.blue); bluebutton.setBounds(120, 5, 15, 15); bluebutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < maincolor = Color.blue; colorbutton.setBackground(maincolor); >>); colorbar.add(bluebutton); JButton cyanbutton = new JButton(); cyanbutton.setBackground(Color.cyan); cyanbutton.setBounds(140, 5, 15, 15); cyanbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < maincolor = Color.cyan; colorbutton.setBackground(maincolor); >>); colorbar.add(cyanbutton); JButton magentabutton = new JButton(); magentabutton.setBackground(Color.magenta); magentabutton.setBounds(160, 5, 15, 15); magentabutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < maincolor = Color.magenta; colorbutton.setBackground(maincolor); >>); colorbar.add(magentabutton); JButton whitebutton = new JButton(); whitebutton.setBackground(Color.white); whitebutton.setBounds(180, 5, 15, 15); whitebutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < maincolor = Color.white; colorbutton.setBackground(maincolor); >>); colorbar.add(whitebutton); JButton blackbutton = new JButton(); blackbutton.setBackground(Color.black); blackbutton.setBounds(200, 5, 15, 15); blackbutton.addActionListener(new ActionListener() < public void actionPerformed(ActionEvent event) < maincolor = Color.black; colorbutton.setBackground(maincolor); >>); colorbar.add(blackbutton); colorbar.setLayout(null); f.add(colorbar); tcc = new JColorChooser(maincolor); tcc.getSelectionModel().addChangeListener(new ChangeListener() < public void stateChanged(ChangeEvent e) < maincolor = tcc.getColor(); colorbutton.setBackground(maincolor); >>); japan.addMouseMotionListener(new MouseMotionAdapter() < public void mouseDragged(MouseEvent e) < if (pressed==true) < Graphics g = imag.getGraphics(); Graphics2D g2 = (Graphics2D)g; // установка цвета g2.setColor(maincolor); switch (rezhim) < // карандаш case 0: g2.drawLine(xPad, yPad, e.getX(), e.getY()); break; // кисть case 1: g2.setStroke(new BasicStroke(3.0f)); g2.drawLine(xPad, yPad, e.getX(), e.getY()); break; // ластик case 2: g2.setStroke(new BasicStroke(3.0f)); g2.setColor(Color.WHITE); g2.drawLine(xPad, yPad, e.getX(), e.getY()); break; >xPad=e.getX(); yPad=e.getY(); > japan.repaint(); > >); japan.addMouseListener(new MouseAdapter() < public void mouseClicked(MouseEvent e) < Graphics g = imag.getGraphics(); Graphics2D g2 = (Graphics2D)g; // установка цвета g2.setColor(maincolor); switch (rezhim) < // карандаш case 0: g2.drawLine(xPad, yPad, xPad+1, yPad+1); break; // кисть case 1: g2.setStroke(new BasicStroke(3.0f)); g2.drawLine(xPad, yPad, xPad+1, yPad+1); break; // ластик case 2: g2.setStroke(new BasicStroke(3.0f)); g2.setColor(Color.WHITE); g2.drawLine(xPad, yPad, xPad+1, yPad+1); break; // текст case 3: // устанавливаем фокус для панели, // чтобы печатать на ней текст japan.requestFocus(); break; >xPad=e.getX(); yPad=e.getY(); pressed=true; japan.repaint(); > public void mousePressed(MouseEvent e) < xPad=e.getX(); yPad=e.getY(); xf=e.getX(); yf=e.getY(); pressed=true; >public void mouseReleased(MouseEvent e) < Graphics g = imag.getGraphics(); Graphics2D g2 = (Graphics2D)g; // установка цвета g2.setColor(maincolor); // Общие рассчеты для овала и прямоугольника int x1=xf, x2=xPad, y1=yf, y2=yPad; if(xf>xPad) < x2=xf; x1=xPad; >if(yf>yPad) < y2=yf; y1=yPad; >switch(rezhim) < // линия case 4: g.drawLine(xf, yf, e.getX(), e.getY()); break; // круг case 5: g.drawOval(x1, y1, (x2-x1), (y2-y1)); break; // прямоугольник case 6: g.drawRect(x1, y1, (x2-x1), (y2-y1)); break; >xf=0; yf=0; pressed=false; japan.repaint(); > >); japan.addKeyListener(new KeyAdapter() < public void keyReleased(KeyEvent e) < // устанавливаем фокус для панели, // чтобы печатать на ней текст japan.requestFocus(); >public void keyTyped(KeyEvent e) < if(rezhim==3)< Graphics g = imag.getGraphics(); Graphics2D g2 = (Graphics2D)g; // установка цвета g2.setColor(maincolor); g2.setStroke(new BasicStroke(2.0f)); String str = new String(""); str+=e.getKeyChar(); g2.setFont(new Font("Arial", 0, 15)); g2.drawString(str, xPad, yPad); xPad+=10; // устанавливаем фокус для панели, // чтобы печатать на ней текст japan.requestFocus(); japan.repaint(); >> >); f.addComponentListener(new ComponentAdapter() < public void componentResized(java.awt.event.ComponentEvent evt) < // если делаем загрузку, то изменение размеров формы // отрабатываем в коде загрузки if(loading==false) < japan.setSize(f.getWidth()-40, f.getHeight()-80); BufferedImage tempImage = new BufferedImage(japan.getWidth(), japan.getHeight(), BufferedImage.TYPE_INT_RGB); Graphics2D d2 = (Graphics2D) tempImage.createGraphics(); d2.setColor(Color.white); d2.fillRect(0, 0, japan.getWidth(), japan.getHeight()); tempImage.setData(imag.getRaster()); imag=tempImage; japan.repaint(); >loading=false; > >); f.setLayout(null); f.setVisible(true); > public static void main(String[] args) < SwingUtilities.invokeLater(new Runnable() < public void run() < new ImageEdit(); >>); > class ColorDialog extends JDialog < public ColorDialog(JFrame owner, String title) < super(owner, title, true); add(tcc); setSize(200, 200); >> class MyFrame extends JFrame < public void paint(Graphics g) < super.paint(g); >public MyFrame(String title) < super(title); >> class MyPanel extends JPanel < public MyPanel() < >public void paintComponent (Graphics g) < if(imag==null) < imag = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB); Graphics2D d2 = (Graphics2D) imag.createGraphics(); d2.setColor(Color.white); d2.fillRect(0, 0, this.getWidth(), this.getHeight()); >super.paintComponent(g); g.drawImage(imag, 0, 0,this); > > // Фильтр картинок class TextFileFilter extends FileFilter < private String ext; public TextFileFilter(String ext) < this.ext=ext; >public boolean accept(java.io.File file) < if (file.isDirectory()) return true; return (file.getName().endsWith(ext)); >public String getDescription() < return "*"+ext; >> >
Работаем с графикой. Основы
Цель нашего урока — понять основы графики. Мы напишем простую рисовалку — хотя это слишком громко сказано. Пока мы сами рисовать ничего не будем — за нас это будет делать глупая машина, т.е. Android. Но тем не менее некоторые полезные вещи мы узнаем, а значит повысим свой профессиональный уровень. Продолжить своё обучение можно в разделе Котошоп.
Создадим новый проект SimplePaint. Создадим новый класс Draw2D, который будет наследоваться от View. Именно в этом классе мы и будем проводить графические опыты. Щёлкаем правой кнопкой мыши на имени пакета и выбираем в меню New | Kotlin Class/File или New | Java Class. В открывшемся диалоговом окне устанавливаем имя для класса Draw2D.
// Kotlin package ru.alexanderklimov.simplepaint import android.content.Context import android.graphics.Canvas import android.view.View class Draw2D(context: Context?) : View(context) < override fun onDraw(canvas: Canvas?) < super.onDraw(canvas) >>
// Java package ru.alexanderklimov.simplepaint; public class Draw2D extends View < public Draw2D(Context context) < super(context); >@Override protected void onDraw(Canvas canvas) < super.onDraw(canvas); >>
В данном коде мы наследуемся от класса android.view.View и переопределяем метод класса onDraw().
Далее необходимо загрузить созданный класс при старте программы. Открываем основной файл активности MainActivity и заменяем строчку после super.onCreate(savedInstanceState):
// Kotlin setContentView(R.layout.activity_main) val draw2D = Draw2D(this) setContentView(draw2D)
// Java // эта строчка нам не нужна setContentView(R.layout.activity_main); Draw2D draw2D = new Draw2D(this); setContentView(draw2D);
В нашем случае мы говорим системе, что не нужно загружать разметку в экран активности. Вместо неё мы загрузим свой класс, у которого есть свой холст для рисования.
Подготовительные работы закончены. Перейдём к графике. Весь дальнейший код мы будем писать в классе Draw2D. Совсем коротко о теории рисования. Для графики используется холст Canvas — некая графическая поверхность для рисования. Прежде чем что-то рисовать, нужно определить некоторые параметры — цвет, толщина, фигура. Представьте себе, что вы рисуете на бумаге и в вашем распоряжении есть цветные карандаши, фломастеры, кисть, циркуль, ластик и т.п. Например, вы берёте толстый красный фломастер и рисуете жирную линию, затем берёте циркуль с жёлтым карандашом и рисуете окружность. Улавливаете аналогию? Теория закончена.
Вся работа с графикой происходит в методе onDraw() класса Draw2D. Создадим виртуальную кисть в классе. В методе укажем, что будем закрашивать всю поверхность белым цветом:
// Kotlin private val paint: Paint = Paint() override fun onDraw(canvas: Canvas?) < super.onDraw(canvas) paint.apply < style = Paint.Style.FILL // стиль Заливка color = Color.WHITE // закрашиваем холст белым цветом >canvas?.drawPaint(paint) >
// Java private Paint mPaint = new Paint(); @Override protected void onDraw(Canvas canvas) < super.onDraw(canvas); // стиль Заливка mPaint.setStyle(Paint.Style.FILL); // закрашиваем холст белым цветом mPaint.setColor(Color.WHITE); canvas.drawPaint(mPaint); >
Итак, холст готов. Далее начинается собственно рисование. Следуя описанному выше принципу мы задаём перед каждым рисованием свои настройки и вызываем нужный метод. Например, для того, чтобы нарисовать жёлтый, круг мы включаем режим сглаживания, устанавливаем жёлтый цвет и вызываем метод drawCircle() с нужными координатами и заливаем окружность выбранным цветом. Получилось симпатичное солнышко.
// Kotlin paint.apply < isAntiAlias = true color = Color.YELLOW >canvas?.drawCircle(950F, 30F, 25F, paint)
// Java // Рисуем жёлтый круг mPaint.setAntiAlias(true); mPaint.setColor(Color.YELLOW); canvas.drawCircle(950, 30, 25, mPaint);
Всегда соблюдайте очерёдность рисования. Если вы поместите данный код до заливки холста белым цветом, то ничего не увидите. У вас получится, что вы сначала нарисовали на стене солнце, а потом заклеили рисунок обоями.
Для рисования зелёного прямоугольника мы также задаём координаты и цвет. У нас получится красивая лужайка.
// Kotlin paint.color = Color.GREEN canvas?.drawRect(20F, 650F, 950F, 680F, paint)
// Java mPaint.setColor(Color.GREEN); canvas.drawRect(20, 650, 950, 680, mPaint);
Далее выведем текст поверх лужайки, чтобы все видели, что она предназначена только для котов. Устанавливаем синий цвет, стиль заливки, режим сглаживания и размер прямоугольника, в который будет вписан наш текст.
// Kotlin paint.apply < color = Color.BLUE style = Paint.Style.FILL isAntiAlias = true textSize = 32F >canvas?.drawText("Лужайка только для котов", 30F, 648F, paint)
// Рисуем текст mPaint.setColor(Color.BLUE); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); mPaint.setTextSize(32); canvas.drawText("Лужайка только для котов", 30, 648, mPaint);
При желании можно вывести текст под углом. Пусть это будет лучик солнца.
// Kotlin private val rect: Rect = Rect() val x = 810F val y = 190F paint.apply < color = Color.GRAY style = Paint.Style.FILL textSize = 27F >val str2rotate = "Лучик солнца!" canvas?.save() canvas?.rotate(-45F, x + rect.exactCenterX(), y + rect.exactCenterY()) canvas?.drawText(str2rotate, x, y, paint) canvas?.restore()
// Java // до метода onDraw() private Rect mRect = new Rect(); // Текст под углом int x = 810; int y = 190; mPaint.setColor(Color.GRAY); mPaint.setTextSize(27); String str2rotate = "Лучик солнца!"; canvas.save(); // Создаём ограничивающий прямоугольник для наклонного текста // поворачиваем холст по центру текста canvas.rotate(-45, x + mRect.exactCenterX(), y + mRect.exactCenterY()); // Рисуем текст mPaint.setStyle(Paint.Style.FILL); canvas.drawText(str2rotate, x, y, mPaint); // восстанавливаем холст canvas.restore();
И завершим нашу композицию выводом рисунка из ресурсов.
// Выводим изображение canvas.drawBitmap(mBitmap, 450, 530, mPaint);
В данном примере я вручную подбирал размеры и координаты фигур для экрана свого телефона. В реальных приложениях необходимо сначала вычислить размеры экрана у пользователя, а потом уже выводить фигуры в соответствии с полученными результатами. Иначе получится так, что некоторые элементы композиции просто не попадут на экран при вращении устройства. Допустим, в альбомном режиме вы установите у точки X значение 800, но в портретном режиме ширина экрана будет, скажем, 480, и точка окажется вне поле зрения. Поэтому следует позаботиться о вычислениях размеров экрана и плясать от этой печки. Ниже представлен немного переделанный вариант для общего понимания.
Финальный рисунок выглядит следующим образом в двух ориентациях. Вы можете доработать приложение, уменьшив размеры кота и т.д.
Исходный код класса
// Kotlin package ru.alexanderklimov.simplepaint import android.content.Context import android.content.res.Resources import android.graphics.* import android.view.View import android.graphics.BitmapFactory class Draw2D(context: Context?) : View(context) < private val paint: Paint = Paint() private val rect: Rect = Rect() val res: Resources = this.resources private var bitmap: Bitmap = BitmapFactory.decodeResource(res, R.drawable.cat) override fun onDraw(canvas: Canvas?) < super.onDraw(canvas) paint.apply < style = Paint.Style.FILL // стиль Заливка color = Color.WHITE // закрашиваем холст белым цветом >canvas?.drawPaint(paint) // Солнце paint.apply < isAntiAlias = true color = Color.YELLOW >canvas?.drawCircle(width - 30F, 30F, 25F, paint) // Лужайка paint.color = Color.GREEN canvas?.drawRect(0F, height - 30F, width.toFloat(), height.toFloat(), paint) // Текст над лужайкой paint.apply < color = Color.BLUE style = Paint.Style.FILL isAntiAlias = true textSize = 32F >canvas?.drawText("Лужайка только для котов", 30F, height - 32F, paint) // Лучик солнца val x = width - 170F val y = 190F paint.apply < color = Color.GRAY style = Paint.Style.FILL textSize = 27F >val beam = "Лучик солнца!" canvas?.save() canvas?.rotate(-45F, x + rect.exactCenterX(), y + rect.exactCenterY()) canvas?.drawText(beam, x, y, paint) canvas?.restore() canvas?.drawBitmap( bitmap, (width - bitmap.width).toFloat(), (height - bitmap.height - 10).toFloat(), paint ) > >
//Java // Если этот код работает, его написал Александр Климов, // а если нет, то не знаю, кто его писал. package ru.alexanderklimov.simplepaint; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.view.View; public class Draw2D extends View < private Paint mPaint = new Paint(); private Rect mRect = new Rect(); private Bitmap mBitmap; public Draw2D(Context context) < super(context); // Выводим значок из ресурсов Resources res = this.getResources(); mBitmap = BitmapFactory.decodeResource(res, R.drawable.cat_bottom); >@Override protected void onDraw(Canvas canvas) < super.onDraw(canvas); int width = canvas.getWidth(); int height = canvas.getHeight(); // стиль Заливка mPaint.setStyle(Paint.Style.FILL); // закрашиваем холст белым цветом mPaint.setColor(Color.WHITE); canvas.drawPaint(mPaint); // Рисуем жёлтый круг mPaint.setAntiAlias(true); mPaint.setColor(Color.YELLOW); // canvas.drawCircle(950, 30, 25, mPaint); canvas.drawCircle(width - 30, 30, 25, mPaint); // Рисуем зелёный прямоугольник mPaint.setColor(Color.GREEN); // canvas.drawRect(20, 650, 950, 680, mPaint); canvas.drawRect(0, canvas.getHeight() - 30, width, height, mPaint); // Рисуем текст mPaint.setColor(Color.BLUE); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); mPaint.setTextSize(32); // canvas.drawText("Лужайка только для котов", 30, 648, mPaint); canvas.drawText("Лужайка только для котов", 30, height - 32, mPaint); // Текст под углом // int x = 810; int x = width - 170; int y = 190; mPaint.setColor(Color.GRAY); mPaint.setTextSize(27); String beam = "Лучик солнца!"; canvas.save(); // Создаём ограничивающий прямоугольник для наклонного текста // поворачиваем холст по центру текста canvas.rotate(-45, x + mRect.exactCenterX(), y + mRect.exactCenterY()); // Рисуем текст mPaint.setStyle(Paint.Style.FILL); canvas.drawText(beam, x, y, mPaint); // восстанавливаем холст canvas.restore(); // Выводим изображение // canvas.drawBitmap(mBitmap, 450, 530, mPaint); canvas.drawBitmap(mBitmap, width - mBitmap.getWidth(), height - mBitmap.getHeight() - 10, mPaint); >>
Android SDK: создание приложения для рисования — сенсорное взаимодействие
В серии нескольких статье мы создадим приложение для рисования с помощью пальцев для Android, использующее сенсорное взаимодействие. У пользователя будет возможность выбирать цвет из цветовой палитры, размер кисти, стирать, создавать новый рисунок или сохранять уже существующий в галерее устройства.
Формат урока
Данный урок по созданию приложения для рисования будет состоять из трех частей:
- Создание интерфейса
- Сенсорное взаимодействие
- Основные функции
Просмотр конечного результата
В первой части серии нескольких уроков мы создадим пользовательский интерфейс. Во второй части мы осуществим рисование на холсте и выбор цветов. В заключительной части мы представим возможность стирать, создавать новые рисунки и сохранять их в галерее пользовательского устройства. Мы рассмотрим опции, которые вы сможете использовать для улучшения этого приложения, проходя в будущем другие учебные материалы, включая заливку холста, прозрачность и другое взаимодействие, отличное от сенсорного.
1. Подготовка к рисованию
Шаг 1
В прошлый раз мы создали класс с именем «DrawingView», который представляет собой пользовательский View для функций рисования, которые должны выполняться внутри. Мы создали схему объявления класса и метод с именем «setupDrawing» — вот сейчас мы сделаем это. В своем классе DrawingView добавьте следующие операторы импорта:
import android.graphics.Bitmap;
import android.graphics.Canvas;