Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 22.01.2017
Сообщений: 11

Переменная не "читается" методом

24.01.2017, 20:19. Показов 761. Ответов 4

Студворк — интернет-сервис помощи студентам
Здравствуйте! Я пишу программу, работающую с bmp. В программе есть несколько классов: класс imageMain содержит меню, a класс imageIO содержит несколько методов. Последовательность действий пользователя следующая: пользователь открывает изображение и обрабатывает его. Затем, после нажатия клавиши <Сохранить> (листинг №1, строки 58-63), должно происходить сохранение изображения методом saveImage (класс imageIO) (листинг №2, строки 60-96), однако сохранения не происходит. Возможно проблема в переменной testImage которая либо не передается методу, либо не обрабатывается верно, либо что-то ещё. Возможно проблема связана с т.н. "замыканиями". Однако, я могу ошибаться т.к. я только изучаю Java. Подскажите пожалуйста направление в котором «копать». Буду благодарен за любую помощь.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import java.util.*;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import javax.swing.*;
 
public class imageMain extends JFrame{
 
static public BufferedReader console = new BufferedReader(
    new InputStreamReader(System.in));
 
////////////////////////////// main ///////////////////////////////
public static void main(String[] args) {
    new imageMain();
} // конец main()
    imageMain(){
///////Тут было меню. Удалил, чтобы не загромождать сообщение //////////////
//Для обработки пути к изображению исп. path, реализованная в виде
// массива из 1го элемента, т.к. java не поддерживает т.н. "замыкания"
final String path[] = {null};
;//Далее – проблемный участок кода. Исправил переменную testImage, как потребовал компилятор
final int[][][] testImage = null;
//Обработка нажатия кнопок меню. Таким образом в программе происходит загрузка,
//обработка а затем Сохранение изображения (сохранение не работает).
//Кнопка 1 - <Открыть файл> (открывается в диал.окне)
        imgFileItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent event){
// количество строк - testImage.length
// количество столбцов - testImage[0].length
                JFileChooser fileopen = new JFileChooser();
                int ret = fileopen.showDialog(null, "Открыть файл");
                if (ret == JFileChooser.APPROVE_OPTION) {
                File file = fileopen.getSelectedFile();
                    path[0] =  file.toString();
                }
            }
        });
//Кнопка 2 - <Преобразовать> (Служить для демонстрации действий с пикселями, добавляет вертикальные черные полосы) 
        op0Item.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent event){
            saveItem.setEnabled(true);
                int[][][] testImage = imageIO.loadImage(path[0]);
                final int MAXROWS = testImage.length;
                final int MAXCOLS = testImage[0].length;
                for (int row=0; row<MAXROWS; row++) {
                    for (int col=0; col<MAXCOLS; col++) {
                        if (col % 30 > 22) { 
                            testImage[row][col][RED]   = 0;
                            testImage[row][col][GREEN] = 0;
                            testImage[row][col][BLUE]  = 0;
                        }
                    }
                }
            }
        });
//Кнопка 3 - <Сохранить> - с ней то и проблема
        saveItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent event){
                imageIO.saveImage(testImage);//не читает testImage
            }
        });
    }
} // конец imageMain


Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import java.awt.*;
import java.awt.image.*;
import java.awt.MediaTracker.*;
import java.io.*;
import javax.swing.JOptionPane;
 
public class imageIO{
 
//Метод loadImage
    public static int[][][] loadImage(String path) {
 
    Image img = (Image)null;
 
    try{
        while (img == null) {
            String openName = null;
            openName = path;
            if (openName.endsWith(".bmp")) {
                img = utils.loadbitmap("./", openName);
            }
            else {
                img=(Image)null;
            }
 
            if (img != null) {
                //Используем в качестве параметра для MediaTracker-а:
                Button b = new Button();
                MediaTracker tracker = new MediaTracker(b);
                tracker.addImage(img,0);
                tracker.waitForID(0);
                // Создаем "observer", обьект позволяющий получить
                // ширину getWidth и высоту getHeight.
                iObserver observer = new iObserver();
                int width = img.getWidth(observer);
                int height = img.getHeight(observer);
                if(width==-1 || height==-1){
                    img = (Image)null;
                }
            }
            if (img == null) {
                System.out.println("Невозможно загрузить указанное изображение из файла: " +openName);
            } // if
        } // while
    } // try
 
        catch(InterruptedException e) {
            System.out.println(e);
            System.exit(1);
        }
        int[][][] imagePixels = getImagePixels(img);
        return imagePixels;
    } // loadImage
 
///////////////////// Тут был метод getImagePixels //////////////////////////
 
//////////////////////////// Метод saveImage //////////////////////////////
// Сохраняет imagePixels как bitmap (.bmp).
// imagePixels - 3D массив пикселей
 
    public static void saveImage(int[][][] imagePixels){
        int height = imagePixels.length;
        int width = imagePixels[0].length;
        int[][] flat = new int[width*height][4];
 
        String saveName = null;
 
        System.out.print("Укажите под каким именем сохранить файл: ");
            try{
        saveName = imageMain.console.readLine();
        }
        catch(IOException e){  
            System.out.println(e);
            System.exit(1);
        }
        // Если saveName не заканчивается на .bmp, добавляем .bmp
        saveName=bmpTack(saveName);
        // Разбиваем пиксельные данные на 2D массив
        int index=0;
        for(int row=0; row<height; row++) {
            for(int col=0; col<width; col++) {
                for(int rgbo=0; rgbo<4; rgbo++) {
                    flat[index][rgbo]=imagePixels[row][col][rgbo];
                }
            index++;
            }
        }
        int[] outPixels = new int[flat.length];
        for(int j=0; j<flat.length; j++) {
            outPixels[j] = ((flat[j][0]&0xff)<<16) | ((flat[j][1]&0xff)<<8) | (flat[j][2]&0xff) | ((flat[j][3]&0xff)<<24);
        }
        // Записываем в файл под именем saveName.
        BMPFile bmpf = new BMPFile();
        bmpf.saveBitmap(saveName, outPixels, width, height);
        System.out.println("Сохранено как " + saveName);
    }
 
///////////////////////////// Метод bmpTack /////////////////////////////
 
} // конец class-а imageIOm
Добавлено через 22 часа 34 минуты
Понимаю, что в таком коде сложно разобраться. Поэтому написал вот такую программу, чтобы тонны кода не отвлекали от основного вопроса:

Необходимо передать методу многомерный массив. Комментарии с уточнениями по ходу кода.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
 
public class imageMain {
    public static void main(String[] args) {
        new imageMain();
    }
 
    imageMain(){
    ////////////////////////Оболочка//////////////////////////
        JFrame frame = new JFrame("Программа обработки изображений");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(null) ;
        frame.setVisible(true);
        Font font = new Font("Arial", Font.PLAIN, 12);
    
        JMenu fileMenu = new JMenu("Файл");
        fileMenu.setFont(font);
    
        JMenuItem imgFileItem = new JMenuItem("Изображение");
        imgFileItem.setFont(font);
        fileMenu.add(imgFileItem);
    
        final JMenuItem saveItem = new JMenuItem("Сохранить");
        saveItem.setFont(font);
        fileMenu.add(saveItem);
        saveItem.setEnabled(false);
    
        JMenuBar menuBar = new JMenuBar();
        menuBar.add(fileMenu);
        frame.setJMenuBar(menuBar);
    
        frame.setPreferredSize(new Dimension(650, 450));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    ////////////////////////Оболочка//////////////////////////
    
        final int[][][] testImage = {null};//3D массив (в нем то и загвоздка)
        final int MAXROWS = 0;//Переменные для примера [int, 3 штуки]
        final int MAXCOLS = 0;
        final int Zamykanie[] = {0};
        
        imgFileItem.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent event){
            final int MAXROWS = 100500;
            System.out.println("Значение MAXROWS: "+MAXROWS);
            final int MAXCOLS = 101;
            System.out.println("Значение MAXCOLS: "+MAXCOLS);
            saveItem.setEnabled(true);
            System.out.println("Было: Zamykanie = "+Zamykanie[0]);
            Zamykanie[0] = 22;
            System.out.println("Задаем: Zamykanie = "+Zamykanie[0]);
            testImage[0][0][1] = 7;
        }});
        
        saveItem.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent event){
        //Если выполнять последовательно imgFileItem, а затем saveItem,
        //то, по идее, MAXROWS и MAXCOLS должны существовать,
        //однако, похоже, их "зачистили"
        //Слышал, что это называется "замыкание"
        //"Лечиться" с помощью массива из 1-го элемента:
            System.out.println("\nА тут уже они не существуют:");
            System.out.println("MAXROWS = "+MAXROWS);
            System.out.println("MAXCOLS = "+MAXCOLS);
            System.out.println("A с этой все норм: Zamykanie = "+Zamykanie[0]);
        // Требуется передать в другой класс: imageIO.saveImage(testImage);
        // C Zamykanie работает (его «читает», но это int а не многомерный массив)
        // Где testImage это <final int[][][] testImage = {null};> трехмерный массив
        // Пробовал как:
        // final int[][][][]Arr = {null};
        // А затем:
        // Arr[0]= testImage;
        // Но не получилось  :(
        }});
    }//конец body
}//конец imagemain
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.01.2017, 20:19
Ответы с готовыми решениями:

В одном классе не "читается" переменная из другого
Подскажите пожалуйста, почему возникает проблема с isTurned? То есть функция checker() не выполняется. Я пробовал инициализировал boolean...

Не читается внешняя переменная в php методом GET
Пытаюсь прочитать внешнюю переменную в php, но она не читается. Делаю так: &lt;?php include_once(&quot;config.php&quot;); ...

Не читается переменная в запросе
Есть код &lt;html&gt; &lt;head&gt; &lt;title&gt;Удалить ответ&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;form action=&quot;chePoi.php&quot; method=&quot;POST&quot;&gt;&lt;?php ...

4
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7392 / 4819 / 1246
Регистрация: 30.03.2015
Сообщений: 13,694
Записей в блоге: 29
25.01.2017, 21:22
Действительно замыкание!
1. Если ты новичок, то почему не начать с программ попроще?
2. Понятно что ты повырезал кода, но я подозреваю что проблема в области видимости, переменная testImage из 24 строки и из строки 44 это разные объекты. Подозреваю что ты обрабатываешь все в одной переменной и передаешь на сохранение другую

компилятор у тебя потребовал? серьезно?
вот передаю многомерный массив без проблем
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) {
        int [][][] array = new int[2][2][2];
        array[0][0][0]=1;
        array[0][1][0]=2;
        array[1][0][0]=3;
        array[0][1][1]=4;
        RTFM(array);
        
    }
 
    public static void RTFM(int [][][] arr){
        for (int [][] ar1:arr){
            for (int [] ar2:ar1){
                for (int i:ar2){
                    System.out.print(i);
                }
                System.out.println("\n");
            }
        }
    }
0
0 / 0 / 0
Регистрация: 22.01.2017
Сообщений: 11
26.01.2017, 21:42  [ТС]
Да вы правы, что "Не по Сеньке шапка".
Однако, пока интерес не остыл, тем более проблема выглядит не сложно.

Строка 24 - это была моя инициатива. Компилятор писал "testImage cannot be resolved to a variable". Одним из "быстрых решений" предложенных им было объявить переменную, вот я и... (объявил массив нулевой размерности. зачем? )

В строке 44 "int[][][] testImage = imageIO.loadImage(path[0]);" в 3D массив записываются данные, полученные из класса imageIO методом loadImage. (Если вкратце, то там происходит следующее: в переменную img загружается битмап utils.loadbitmap по "адресу" path[0], далее отсекается заголовок и все лишнее, и остаются только битовые данные. Определяется их размер т.к. он изначально не известен и записывается в переменную (массив imgBitmap), которую возвращает метод). Далее в многомерный (и многострадальный) массив testImage наконец эти битовые данные и перезаписываются.
По идее они и должны были быть там, если бы не сборщик мусора.

А массив testImage (в классе Мейн) получается вроде как динамический т.к. данные изначально записывались в динамический массив imgBitmap, который и возвращает метод loadImage (из класса imageIO). Статический то, я бы осилил.

И самая проблемная - 61-ая строчка, которую не читается "imageIO.saveImage(testImage);". В ней просто передаем методу saveImage в класс imageIO наш массив testImage.

Может подскажете, с учетом вышеизложенного, что-нибудь, хотя-бы в виде алгоритма (если фрагменты кода приложите, то только +).
Возможно ли как-то решить эту задачу с помощью указателей на объект. (и как быть если массив динамический)

Заранее благодарен.
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7392 / 4819 / 1246
Регистрация: 30.03.2015
Сообщений: 13,694
Записей в блоге: 29
27.01.2017, 20:43
Цитата Сообщение от Карабасыч Посмотреть сообщение
По идее они и должны были быть там, если бы не сборщик мусора.
Ты о чем вообще? сборщик мусора удаляет объекты на которые нет ссылок, причем он запускается только когда память уже порядком подзанята. Он не удаляет значения из массива, по крайней мере я никогда даже не слышал о таком

Единственный вариант и сразу полезный скилл -использовать дебаг, ставит брекпоинты и отслеживать значения переменных, где то ты их теряешь. Мое предположение все еще в силе -ты используешь разные объекты при работе и сохранении.

Не по теме:

Если бы ты бокс решил осваивать то сразу бы попер с разрядниками спарринговать или может полгодика по груше поработать и лапам?

1
0 / 0 / 0
Регистрация: 22.01.2017
Сообщений: 11
27.01.2017, 20:59  [ТС]
Спасибо, я понял.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.01.2017, 20:59
Помогаю со студенческими работами здесь

Глобальная переменная не читается в новом потоке
подскажите пожалуйста, у меня есть помимо главного еще 2 потока и есть глобально объявленный массив, заполняю я его в первом потоке, там же...

[Мозговой штурм от MSmyk1999] Не читается переменная
Приветствую вас, дорогие друзья! Перейду к проблеме. Есть папка. В ней два файла php: config.php footer.php Объявление в...

Не передается переменная методом POST
Здравствуйте. Я хочу передать значение из одного файла в другой через метод post, а именно, после нажатия кнопки &quot;Списать книгу&quot;....

Не передается переменная методом POST
Я уже битый час не могу разобраться почему у меня не хочет передаваться значение переменной (из файла в этот же файл). Скрипт читает...

Не передается переменная методом POST
Здравствуйте! Есть вот такая функция: function userrr() { $user= wp_get_current_user(); //$log = $user-&gt;user_login; $log =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
1С: Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит значение перечислений. / / Событие "НачалоВыбора" реквизита на форме. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru