Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java ME (J2ME) > Разворот картинки |
Автор: Jlekc 1.8.2005, 11:57 | ||
нужно было релизовать разворот картинки (используеться MIDP 2.0) полазил по нету, нашол подобный премер:
последний параметр - трансформация картинки, методом тыка определил значения кторые нужны мне для работы, но так и не смог отыскать список флагов кторые пренемает transform. есе ктото видел, былоб интересно знать |
Автор: javastic 1.8.2005, 14:16 | ||
То что тебе надо сидит в классе Sprite. Соответственно:
Удачи! |
Автор: Jlekc 1.8.2005, 14:20 |
яс, псиба. ЗЫ: а в продолжения темы, как изменить размер картинки? |
Автор: Nemesis 3.8.2005, 12:16 |
Jlekc, если под изменение картинки подразумевается масштабирование(увеличение или умеьшение), то скажу сразу, что в midp такое не предусмотрено. Но ты можешь "вручную" масшатабировать картинку, т.е. считываешь массив цветов пикселей из картинки - метод public void getRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height) затем манипулируешь массивом rgbData. Если хочешь увеличить картинку -> заводишь еще один массив с новым кол-вом пикселей и по определенному правилу записываешь в него данные(если кому-то нужно будет, могу дать алгоритм), аналогично с уменьшением. Но! прошу заметить, что кол-во элементов(суммарное кол-во элементов во всех массивах в пределах одного мидлета) не должо превышать ~130000. Т.е. сразу несколько картинок(средних размеров) различных масштабов держать не получится.И не получится увеличить картинку размером 176 х 220 в 2 раза, т.к. потребуется массив из 176*2*220*2 = 154880 элементов ![]() |
Автор: Jlekc 3.8.2005, 15:23 |
о тком изврате слышал, но неужели нету встроеного метода? |
Автор: javastic 4.8.2005, 14:38 |
Нету. Можно порыскать в Инете на предмет готовых решений и использовать в своём проекте. |
Автор: 111 5.2.2006, 02:50 |
Привет. Есть статья где подробно описан http://www.mobilab.ru/articles/76/ на любой угол. Есть рабочий пример. |
Автор: Jlekc 5.2.2006, 13:02 |
хых, позновато) впринципе подобную схему и сам зделал, заль что тогда не наткнулся на готовую |
Автор: 111 24.2.2006, 19:28 |
Тут в другом форуме один чел сказал, что есть более быстрый алгоритм поворота картинки без всяких синусов и умножений. Все на сложении. Кто-нить что знает? |
Автор: Jlekc 24.2.2006, 19:39 |
есе на пярмой угол крутить, то мона и без синусов обойтись |
Автор: valerchi 27.5.2008, 23:31 | ||
помогите, пожалуйста. Хочу сделать анимацию, как открывается глаз. загрузил в папку /res шесть фоток(первая -закрытый глаз, вторая - чуть открытый... последняя - совсем открытый). Составил цикл загрузки каждого изображения. На эмуляторе вроде получается, а на телефоне - нет. Во-первых, на телефоне изображение загружается слишком долго, а во-вторых, между загрузкой картинок идёт мерцание и проскакивает йзображение фонового рисунка с телефона. И ещё: я не использовал массив для загрузки и выгрузки изображений. Может дело в этом? Вот мой код:
|
Автор: eugine_s 28.5.2008, 08:52 |
valerchi, загрузи все картинки сразу в память. Анимация тормозит из-за того что время создания картинки очень большое. |
Автор: valerchi 28.5.2008, 16:18 |
Извините за такие простые вопросы, я начинающий... Это как загрузить в память ? То есть загрузить в массив? |
Автор: W0LF 28.5.2008, 17:30 |
как вариант ![]() |
Автор: Dummy 28.5.2008, 17:38 | ||||
Да, создать массив Image, один раз загрузить туда все и хранить. Получится что-то такое:
И единожды вызвать его, например, в startApp() (в конструкторе не очень хочется возиться с I/O, уж больно интимный это участок кода ):
В твоем же коде каждый раз при отрисовке картинки очередной кадр каждый раз грузится из jar-файла, т. е . происходит ковыряние в zip'е на файловой системе телефона - процесс весьма небыстрый. Правда, если хранить картинки в памяти, стоит оценить, сколько же памяти они будут отъедать. Если много, то стоит подумать, как организовать память оптимальнее. Например, если телефон поддерживает CLDC 1.1, хранить не сильные ссылки на Image, а WeakReference. |
Автор: valerchi 28.5.2008, 17:40 |
Я загрузил в массив картинки, но всё осталось также |
Автор: eugine_s 28.5.2008, 18:14 |
и из старого кода убрал загрузку картинок в цикле отрисовке ? Нужно код посмотреть. |
Автор: valerchi 28.5.2008, 19:18 | ||
всё сделал, но результат остался тот же изображение не сливается, идёт мерцание и покадровая загрузка. Вот мой код , может я что не так сделал? .......... Ещё хотел сказать , что у меня картинки разные (какие смог найти ) - разных размеров и рисунков
|
Автор: Dancer 28.5.2008, 19:22 |
да тут большее зло это то, что пытаемся в Form пихать каждую картинку и эту формочку через setCurrent() рисовать. Это очень медленная операция. Для такой анимашки нужно пользовать Canvas и определять paint() для него и рисовать лишь в этом Canvas. То есть при старте аппликухи делается объект класса наследника от Canvas, и именно этот класс пихаем на дисплей, а paint() этой самой канвы и делает отрисовку. как всё отрисовали, повисели малешко, а после этого уже формочку (незабыв почистить память от Image[]) |
Автор: valerchi 28.5.2008, 19:49 | ||
всё сделал, но результат тот же - картинки не сливаются, а покадрово мерцают и проскакивает фоновый рисунок телефона. Вот мой код, может я что сделал нетак
|
Автор: Dummy 28.5.2008, 20:48 | ||||||
valerchi, зло этого кода даже не в медленности операций отрисовки элементов формы по сравнению с канвасом, а в том, что при выполнении такой связки:
на каждой итерации происходит перекомпоновка формы, т. к. setCurrent(null) не скрывает форму. Вызов f.delete(0) приводит к тому, что на форме не остается компонентов, и нужно ее перекомпоновать, чтобы отрисовывался только фон. f.append(i) добавляет новый ImageItem, после чего нужно опять перекомпоновать форму. Тебе предложили для отрисовки использовать примерно следующий подход. Создать потомка от Canvas, который бы в paint() отрисовывал очередной кадр анимации. Например, так:
А потом, где нужно, сделать следующее:
На каждой итерации while будет рисоваться следующий кадр. |
Автор: valerchi 30.5.2008, 02:17 | ||||
Извини, ничего не понял. Я до canvasa ёщё не дошёл - не учил..... Пытаюсь сейчас разобраться, но, думаю, что где-то через неделю разберусь, а хотелось бы сейчас..... Я так понял, что нужно в папке /res создать два файла. Первый назвать AnimationCanvas.java : вот его код:
А второй создать с именнем Glaz.java : Вот его код:
Если можно, объясни, как для "чайника", а нет, буду постепенно разбираться. |
Автор: Dummy 30.5.2008, 09:07 | ||
Form - это Displayable, который рисует свои элементы сам. Canvas - это Displayable, код рисования на котором определяется мидлетописателем. Поэтому общая идея заключалась в том, чтобы выделить рисование анимации в подкласс класса Canvas, который мы с моей легкой руки назвали AnimationCanvas. Этот класс принимает в конструкторе массив кадров, которые он будет один за другим отрисовывать, при каждой новой перерисовке - следующий кадр. Предлагаемая последовательность действий:
Нет. В папку /res по традиции кладутся ресурсы, а не исходники. Не стоит нарушать традицию, тем более что некоторые средства разработки (WTK? не помню уже) , возможно, будут принимать папку /res как предопределенную папку для ресурсов. Ну, например, положи их в /src/app. Тогда в начале каждого файла у тебя будет такая строчка: [code=java] package app [code] И jad-файл тоже нужно будет обновить. Почитай повнимательнее про Canvas, обращая внимание на применение Graphics, repaint() и serviceRepaints(). |
Автор: W0LF 30.5.2008, 12:25 | ||
|
Автор: valerchi 30.5.2008, 14:36 |
Вот, что я попробовал сделать, только не знаю, как очистить "g.drawImage", чтобы очистить картинку, для загрузки новой картинки: Это первый файл Glaz.java : import javax.microedition.lcdui.*; import javax.microedition.midlet.MIDlet; public class Glaz extends MIDlet { private Image i; public void startApp() { // создать объект графика Graph graph = new Graph(); // получить ссылку на менеджер дисплея Display display = Display.getDisplay(this); // вывести график на экран display.setCurrent(graph); // получить строку атрибута имени мидлета } public void pauseApp() { } public void destroyApp(boolean unconditional) { // уведомить систему о завершении notifyDestroyed(); } } Это второй файл Graph.java : import javax.microedition.lcdui.*; import javax.microedition.midlet.MIDlet; import java.io.*; public class Graph extends Canvas { private Image i; private int x; // функция прорисовки экрана public void paint(Graphics g) { for (x=0; x!=19; ++x) { try { i = Image.createImage("/" + Integer.toString(x+1) + ".png"); } catch (IOException ioe) { ioe.printStackTrace(); } } g.drawImage(i, 90, 100, g.HCENTER | g.VCENTER); g.drawImage(255, 255, 255); } } |
Автор: valerchi 30.5.2008, 15:00 | ||
Ничего не понимаю, по идее должно быть так: очищаем экран и добавляем туда картинку и всё это помещаем в цикл повторений. Делаю так :
..... а ничего не получается. Высвечивает только последняя картинка. |
Автор: Dummy 30.5.2008, 17:41 |
Правильно, что высвечивается только последняя. Потому что при каждой перерисовке ты рисуешь 20 картинок на одном и том же месте. А нужно - при каждой перерисовке одну, а затем обновлять индекс. Я уже написал вариант, как это сделать. Смотри внимательнее. |
Автор: valerchi 1.6.2008, 11:35 | ||
Получилось вот, что :
Массив я не брал, хотел сделать всё проще. Но на эмуляторе картинки налаживаются друг на друга. Как сделать, чтобы очистить экран, а потом показать картинку? |
Автор: Dummy 1.6.2008, 13:47 |
Брр. Что-то мы ходим вокруг одного и того же... Примерно с такого же по эффективности решения мы и начинали ![]() Затирать на канвасе можно только заливкой экрана фоновым цветом или рисованием фоновой картинки. Все делается ручками. |
Автор: valerchi 1.6.2008, 15:41 | ||
Ничего не понимаю, уже очистил экран, - залил его белым, а всё равно картинки налаживаются друг на друга
Добавлено через 4 минуты и 53 секунды Всё, на счёт "закраски" разобрался, сейчас попробую в телефоне. |
Автор: eugine_s 1.6.2008, 17:01 |
valerchi, ты уж извини за прямоту, но этот код - ужасный. Лучше отложи куда-нибудь подальше этот код и начни с "чистого листа". Возьми какой-нибудь пример хороший. Ошибки: 1. Никаких тяжелых действий в startApp(). Можно с этим много "горя" получить в будущем. 2. Зачем 19-ть (или 18-ть) раз выполнять вот такое: // получить ссылку на менеджер дисплея d = Display.getDisplay(this); // создать объект графика Ggraph graph = new Ggraph(); 3. Зачем: // вывести график на экран d.setCurrent(graph); достаточно один раз сделать такое, а потом graph.repaint(); (возможно graph.serviceRepaint() перед repaint() вызвать) 4. g.fillRect(255, 255, 255, 255); - это какой ты прямоугольник зарисовываешь? 5. (Основное) Где картинки загруженные в массив? Они ведь в у тебя опять перед отрисовкой загружаются. |
Автор: eugine_s 1.6.2008, 17:49 |
Почитай вот http://www.mobilab.ru/articles/index2.php?cat=3 много полезный статей про j2me По твоему вопросу там есть * Пишем игру для телефона. (Части 1 - 6) |
Автор: valerchi 6.6.2008, 01:22 | ||
Спасибо, вроде всё нормально. Смотри, что у меня получилось. И самое главное - работает на эмуляторе и на телефоне. Теперь, хотелось бы добавить команду "Back", чтобы программу можнобыло "запустить в обратную сторону". Как это можно сделать?
|
Автор: eugine_s 6.6.2008, 12:54 | ||
Все равно в startApp куча всего осталось - плохая манера. Вот, переделал немного + добавил в два направления анимация
|
Автор: Dummy 6.6.2008, 14:41 |
По большому счету, подход с вычитыванием картинок в конструкторе вряд ли лучше. Тяжеловесность startApp() крайне нежелательна, согласен, т. к. при долгом startApp() у AMS элементарно может возникнуть желание прибить повисший (по ее мнению) в функции-триггере мидлет. Но. В случае, если мы в startApp() схлопочем RuntimeException, по крайней мере будет вызван destroyApp() для нашего мидлета, так что мы сможем обработать эту ситуацию. Скорее всего, смерть мидлета предотвратить мы не сможем (MIDP гласит, что в таком случае мидлет должен быть терминирован). Но, как минимум, закроем ту часть ресурсов, которую мы успешно захватили до получения Exception в startApp(), и покажем предсмертное сообщение пользователю . В случае же, когда мы получаем проблемы в конструкторе, обработка исключительной ситуации целиком отдается на откуп AMS. Она, конечно, может покажет более-менее содержательное сообщение, в конечном итоге даже освободит ресурсы, захваченные нами и не освобожденные. Но ситуация получится намного более брутальная и рискованная. В этом примере такого не получится - просто стартуем без картинок (что само по себе не очень хорошо, но для такого быстрого примера вполне нормально). Но в общем случае - сами понимаете... Поэтому, видимо, лучшим решением будет запуск в startApp() отдельного потока приложения, внутри которого будут и картинки из джара выниматься, и все отрисовки вызываться. |
Автор: valerchi 7.6.2008, 21:34 |
Дело в том, что ты меня не совсем понял. Я хотел сделать так, чтобы нажал кнопку - глаз открылся, и так открытым остался. Потом нажал другую кнопку, - программа пошла в другую сторону, то есть глаз закрылся, а у тебя получается бесконечный цикл, - тое сть глаз всё время моргает. |
Автор: eugine_s 8.6.2008, 18:50 | ||||
Дело в том, что: 1. Из того что ты написал было не понятно что ты хотел получить 2. Из того что я написал, очень просто получается, то что тебе нужно, нужно то изменить 3-4 строчки кода. Вот это
Изменить на вот это:
Т.е. изменения заключаются только в том, чтобы не начинать цикл анимации с самого начала (конца). Конечно, можно улучшить программу: какие-то флаги выставлять, чтобы анимацию не выполняло, чтобы лучше работало.... но уже можешь сам над улучшениями поработать. Да, кстати, то что написал Dummy по поводу инициализации картинок НЕ в конструкторе - правильное и если бы я писал для себя, то так и сделал бы (+ возможно добавил бы метод, который освобождал все эти ресурсы). |
Автор: valerchi 12.6.2008, 12:28 |
Большое спасибо. Всё работает. А можно добавить какую-то надпись вверху, типа бегущей строки? Или сюда невозможно добавить? |
Автор: valerchi 12.6.2008, 16:27 |
Вообще, посоветуйте какую- нибудь литературу по j2me программированию. Я пользуюсь самоучителем Буткевича. |
Автор: Dummy 12.6.2008, 23:57 | ||
См. документацию по Displayable.setTicker(). Ticker - это и есть бегущая строка. Уж не знаю, где она появится - сверху или снизу, - зависит от реализации. В принципе, если надо строго вверху, свою реализацию написать тоже не сложно. По аналогии с анимацией злосчастного глаза))) |
Автор: valerchi 13.6.2008, 23:45 | ||
Сделал так. На эмуляторе строка идёт, а на телефоне - нет. Телефон у меня SonyEricsson w810i. Вчём может быть проблемма?
|
Автор: valerchi 14.6.2008, 22:15 |
Шустрый, объясни в чём причина? Бегущая строка на эмуляторе идёт, а на телефоне - нет. |
Автор: valerchi 16.6.2008, 17:19 |
Загрузил этот код в SonyEricsson K790i, там бегущая строка видна. И получилась другая проблемма: картинка уменьшилась и показывается не в середине экрана, а в левом верхнем углу. Не знаете, в чём может быть проблемма? Как её показать на всех телефонах по середине и не меняя размера? |
Автор: eugine_s 16.6.2008, 18:55 | ||
Вместо Form использовать Canvas. В 99,999% проектов, если есть анимация то будет использовать Canvas для ее отображения |
Автор: valerchi 16.6.2008, 19:10 |
eugine_s, но ведь у меня Canvas (код вверху "Glaz"). И получается, что на SonyEricsson w810i вроде работает, только не отображается бегущая строка, а на SonyEricsson K790i бегущая строка идёт? зато картинка уменьшилась и показывается не в середине экрана, а в левом верхнем углу. |
Автор: valerchi 16.6.2008, 19:54 |
Экраны телефонов ведь разные. Можно ли ввести какие нибудь стандартные координаты, чтобы картинка отображалась посередине в любом телефоне? На моём телефоне координаты: g.drawImage(mas[currentImage], 90, 75, g.HCENTER | g.VCENTER); Но они не подходят на другой телефон с большим, чем у меня экраном. |
Автор: eugine_s 16.6.2008, 20:04 |
Сорри. Забыл уже ![]() Так в чем тогда проблема? getWidth(), getHeigth() - размеры экрана возвращают. Вот код: g.drawImage(mas[currentImage], getWidth() / 2 - mas[currentImage].getWidth() / 2, getHeight() / 2 - mas[currentImage].getHeight() / 2, 0); |
Автор: valerchi 16.6.2008, 20:31 |
eugine_s, ты помнишь мой Glaz? Меня ещё с самого начала поразила такая ерунда - включаешь программу и постоянно идёт бесконечный цикл. Это обязательно? То есть я думал так, - нажимаешь кнопку, цикл пошёл, картинки отлистались, цикл закончился и всё, команда "ок" ждёт следующего нажатия. Опять нажал, опять цикл пошёл, отлистал там сколько- нибудь кадров и опять закончился. |
Автор: Dummy 16.6.2008, 21:40 |
"Эти Glaz'а напротив, калейдоскоп огней..." ![]() По делу - valerchi, так никто ж не мешает тебе повторить цикл всего один раз по каждому нажатию, не стоит учебные примеры воспринимать так буквально ![]() Кстати, по поводу Ticker на w810i - попробуй для интересу добавить Ticker не к канвасу, а к форме, например. Для формы ticker рисуется? |
Автор: valerchi 16.6.2008, 21:40 |
eugine_s, ты помнишь мой Glaz? Меня ещё с самого начала поразила такая ерунда - включаешь программу и постоянно идёт бесконечный цикл. Это обязательно? То есть я думал так, - нажимаешь кнопку, цикл пошёл, картинки отлистались, цикл закончился и всё, команда "ок" ждёт следующего нажатия. Опять нажал, опять цикл пошёл, отлистал там сколько- нибудь кадров и опять закончился. Добавлено через 18 секунд eugine_s, ты помнишь мой Glaz? Меня ещё с самого начала поразила такая ерунда - включаешь программу и постоянно идёт бесконечный цикл. Это обязательно? То есть я думал так, - нажимаешь кнопку, цикл пошёл, картинки отлистались, цикл закончился и всё, команда "ок" ждёт следующего нажатия. Опять нажал, опять цикл пошёл, отлистал там сколько- нибудь кадров и опять закончился. Добавлено через 6 минут и 27 секунд Dummy, ты пишешь "Кстати, по поводу Ticker на w810i - попробуй для интересу добавить Ticker не к канвасу, а к форме, например. Для формы ticker рисуется? " Да в форме бегущая строка у меня отображается, но ведь у меня картинки загружаются в Canvas. Это что в канвас добавить форму? |
Автор: Dummy 16.6.2008, 22:31 |
Нет, в канвас добавлять форму не нужно. Вряд ли получится *^_^* Это я спросил, чтобы проверить, что проблема с отрисовкой тикера существует только для канваса. А можешь попробовать временно закомментировать код отрисовки канваса (тело функции paint)? Будет ли рисоваться тикер? |
Автор: valerchi 16.6.2008, 22:43 | ||
Всё равно бегущей строки нет |
Автор: valerchi 17.6.2008, 12:33 | ||
Извините за назойливость, не могу понять... Я делаю цикл, и в каждом повторении цикла нужно выйти из него, чтобы сделать "repaint()", а потом опять продолжить выполнение цикла, но что-то не получается, программа полностью отлистает цикл, а потом делает один раз "repaint()".
|
Автор: eugine_s 17.6.2008, 13:22 | ||
The call to paint() occurs asynchronously of the call to repaint(). That is, repaint() will not block waiting for paint() to finish. The paint() method will either be called after the caller of repaint() returns to the implementation (if the caller is a callback) or on another thread entirely. В доке все написано. repaint() - это только запрос на перерисовку, а не вызов paint-a. Делай паузы в твоем цикле. |
Автор: valerchi 17.6.2008, 13:40 |
А как её сделать? Добавлено через 7 минут и 9 секунд А как её сделать? |
Автор: Dummy 17.6.2008, 13:59 |
Поставиь wait() или Thread.sleep() на нужное количество миллисекунд после каждого repaint() |
Автор: valerchi 2.7.2008, 16:47 |
У меня получилась небольшая програмка. Что теперь нужно сделать, чтобы её продать? 1. Залицензировать её? 2. Как поставить пароль? |
Автор: Dummy 3.7.2008, 11:59 |
Вот http://forum.vingrad.ru/forum/topic-137013/kw-%D0%B7%D0%B0%D1%89%D0%B8%D1%88%D0%B0%D1%82%D1%8C-%D0%BC%D0%B8%D0%B4%D0%BB%D0%B5%D1%82-%D0%BF%D1%80%D0%BE%D0%B4%D0%B0%D0%B6%D0%B5.html достаточно много копий сломали по этому вопросу. |
Автор: Dummy 3.7.2008, 12:53 |
Да, и у меня еще есть предложение. Открывать на каждый новый вопрос свою тему (предварительно поискав, нет ли чего аналогичного на форуме ![]() |
Автор: valerchi 7.7.2008, 12:50 |
eugine_s, у меня получилась небольшая програмка, ("Эти Glaz'а напротив, калейдоскоп огней..."), ты мне здорово в ней помог. Хочу авторство разделить с тобой. Что скажешь? |
Автор: valerchi 21.5.2009, 21:16 |
Кстати, програмка получилась., может и не лучшего качества, но работает. Смысл в ней такой, что нужно загадать какой-нибудь вопрос, но только, чтобы ответ на него был "да" или "нет", а потом нажимаешь кнопку... Открывается глаз, а в глазе написан ответ "да" или "нет" или "может быть" или "незнаю". Если кто хочет может скачать бесплатно поэтой ссылке: http://www.azov-riba.com/glaz.rar Но предупреждаю, прога работает только на sonyericsson (у меня w810i). |