首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

java基础学习_常用类小结

看看下面的类,是否都熟悉,简要说明每个类主要是干什么呢? Object:是类层次结构的根类,所有类都直接或者间接的继承自该类。 Scanner:获取键盘录入数据的类。 String:针对字符串的常见操作的类。 StringBuffer/StringBuilder:字符串缓冲区类,提高字符串的操作效率。 Arrays:针对数组进行操作的工具类。 Integer:把int基本数据类型封装成Integer引用数据类型,可以调用方法了,最主要作用是可以把String引用数据类型转换int基本数据类型了。 Character:把char基本类型封装成Character引用数据类型,可以调用方法了。了解几个方法就可以了。 Pattern:正则表达式的编译表示形式。模式对象。 Matcher:匹配器对象。 Math:针对数学运算操作的类。 Random:产生随机数的类。 System:系统类,提供了几个有用方法。 BigInteger:关于大整数的运算的类。 BigDecimal:关于浮点数的运算用这个,不会有精度的丢失。 Date:针对日期操作的类,可以精确到毫秒。 DateFormat:针对日期进行格式化或者针对字符串(文本)进行解析的类。 Calendar:日历类,把所有的日历字段(成员变量)进行了封装,要什么,自己使用获取方法,然后拼接。 Object:是类层次结构的根类,所有类都直接或者间接的继承自该类。 Scanner:获取键盘录入数据的类。 String:针对字符串的常见操作的类。 StringBuffer/StringBuilder:字符串缓冲区类,提高字符串的操作效率。 Arrays:针对数组进行操作的工具类。 Integer:把int基本数据类型封装成Integer引用数据类型,可以调用方法了,最主要作用是可以把String引用数据类型转换int基本数据类型了。 Character:把char基本类型封装成Character引用数据类型,可以调用方法了。了解几个方法就可以了。 Pattern:正则表达式的编译表示形式。模式对象。 Matcher:匹配器对象。 Math:针对数学运算操作的类。 Random:产生随机数的类。 System:系统类,提供了几个有用方法。 BigInteger:关于大整数的运算的类。 BigDecimal:关于浮点数的运算用这个,不会有精度的丢失。 Date:针对日期操作的类,可以精确到毫秒。 DateFormat:针对日期进行格式化或者针对字符串(文本)进行解析的类。 Calendar:日历类,把所有的日历字段(成员变量)进行了封装,要什么,自己使用获取方法,然后拼接。我的GitHub地址: https://github.com/heizemingjun 我的博客园地址: http://www.cnblogs.com/chenmingjun 我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun Copyright ©2018 黑泽明军 【转载文章务必保留出处和署名,谢谢!】

优秀的个人博客,低调大师

C++ activemq CMS 学习笔记

很早前就仓促的接触过activemq,但当时太赶时间.后面发现activemq 需要了解的东西实在是太多了. 关于activemq 一直想起一遍文章.但也一直缺少自己的见解.或许是网上这些文章太多了.也可能是自己知识还不足够. 0,activemq-cpp 能解决什么问题. 实际应用就是让开发者能从多线程,多消息通信中解救出来.更多的关注应用逻辑. CMS (stands for C++ Messaging Service) is a JMS-like API for C++ for interfacing with Message Brokers such asApache ActiveMQ. CMS helps to make your C++ client code much neater and easier to follow. To get a better feel for CMS try theAPIReference. ActiveMQ-CPP is a client only library, a message broker such asApache ActiveMQis still needed for your clients to communicate. Our implementation of CMS is called ActiveMQ-CPP, which has an architecture that allows for pluggable transports and wire formats. Currently we support theOpenWireandStompprotocols, both over TCP and SSL, we also now support a Failover Transport for more reliable client operation. In addition to CMS, ActiveMQ-CPP also provides a robust set of classes that support platform independent constructs such as threading, I/O, sockets, etc. You may find many of these utilities very useful, such as a Java like Thread class or the "synchronized" macro that let's you use a Java-like synchronization on any object that implements the activemq::concurrent::Synchronizable interface. ActiveMQ-CPP is released under theApache2.0 License 大意: CMS (C++ 消息 服务)是一个面象apache activemq 的 消息 中间层的C++接口. CMS的实现 叫做activemq-cpp ,不过当前只支持openwire,amqp,TCP,ssl. 现在还支持 主备切换功能(这个是重点,当时我不懂,结果就走了弯路!_!). -_- ,意思是 activemq\conf\activemq.xml中的stomp,mqtt,ws 是没办法的. <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/> </transportConnectors> 1,acticvemq-cpp 的配置使用. 参考:Active MQ C++实现通讯http://blog.csdn.net/lee353086/article/details/6777261 activemq-cpp下载地址: http://activemq.apache.org/cms/download.html 相关依赖库 在http://activemq.apache.org/cms/building.html中是有介绍的.不过是en的. 还是再说下吧.本人en也特差. "With versions of ActiveMQ-CPP 2.2 and later, we have a dependency on theApache Portable Runtimeproject. You'll need to install APR on your system before you'll be able to build ActiveMQ-CPP." "The package contains a complete set of CppUnit tests. In order for you to build an run the tests, you will need to download and install the CppUnit library. Seehttp://cppunit.sourceforge.net/cppunit-wiki" 所以就包含了:apr,apr-iconv,apr-util,cppunit. http://mirrors.hust.edu.cn/apache/apr/ 中可以下载apr,apr-iconv,apr-util(版本号都找最高的,不要一高一低,不然编译会出问题). apr-1.5.1-win32-src.zip, apr-iconv-1.2.1-win32-src-r2.zip, apr-util-1.5.4-win32-src.zip. 解压后记得重命令文件夹,去掉版本号,改成如下图,不然工程编译时默认的 [附加包含目录] 是找不到的. 所有文件夹放在一个根目录下. 打开 activemq-cpp-library\vs2008-build\activemq-cpp.sln 依次添加[现在项目]:libapr.vcproj,libapriconv.vcproj,libaprutil.vcproj. 只需要lib项就行了. 最后项目图: libapriconv.vcproj,libaprutil.vcproj 的[项目依赖项]都需要libapr activemq-cpp的[项目依赖项]需要libapriconv,libaprutil,libapr. activemq-cpp 的[附加包含目录] 需要包含 这三个的的include目录. 经过漫长的编译后, 这个大lib文件就出来. activemq-cpp-example 这个工程 ,就有 hello world 的代码. 2,activemq-cpp-example 项目代码解析. 通过这个项目可以让我们更好的认识 activemq-cpp的结构. /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // START SNIPPET: demo #include <activemq/library/ActiveMQCPP.h> #include <decaf/lang/Thread.h> #include <decaf/lang/Runnable.h> #include <decaf/util/concurrent/CountDownLatch.h> #include <decaf/lang/Integer.h> #include <decaf/lang/Long.h> #include <decaf/lang/System.h> #include <activemq/core/ActiveMQConnectionFactory.h> #include <activemq/util/Config.h> #include <cms/Connection.h> #include <cms/Session.h> #include <cms/TextMessage.h> #include <cms/BytesMessage.h> #include <cms/MapMessage.h> #include <cms/ExceptionListener.h> #include <cms/MessageListener.h> #include <stdlib.h> #include <stdio.h> #include <iostream> #include <memory> using namespace activemq::core; using namespace decaf::util::concurrent; using namespace decaf::util; using namespace decaf::lang; using namespace cms; using namespace std; class HelloWorldProducer : public Runnable { private: Connection* connection; Session* session; Destination* destination; MessageProducer* producer; int numMessages; bool useTopic; bool sessionTransacted; std::string brokerURI; private: HelloWorldProducer(const HelloWorldProducer&); HelloWorldProducer& operator=(const HelloWorldProducer&); public: HelloWorldProducer(const std::string& brokerURI, int numMessages, bool useTopic = false, bool sessionTransacted = false) : connection(NULL), session(NULL), destination(NULL), producer(NULL), numMessages(numMessages), useTopic(useTopic), sessionTransacted(sessionTransacted), brokerURI(brokerURI) { } virtual ~HelloWorldProducer(){ cleanup(); } void close() { this->cleanup(); } virtual void run() { try { // Create a ConnectionFactory auto_ptr<ConnectionFactory> connectionFactory( ConnectionFactory::createCMSConnectionFactory(brokerURI)); // Create a Connection connection = connectionFactory->createConnection(); connection->start(); // Create a Session if (this->sessionTransacted) { session = connection->createSession(Session::SESSION_TRANSACTED); } else { session = connection->createSession(Session::AUTO_ACKNOWLEDGE); } // Create the destination (Topic or Queue) if (useTopic) { destination = session->createTopic("TEST.FOO"); } else { destination = session->createQueue("TEST.FOO"); } // Create a MessageProducer from the Session to the Topic or Queue producer = session->createProducer(destination); producer->setDeliveryMode(DeliveryMode::NON_PERSISTENT); // Create the Thread Id String string threadIdStr = Long::toString(Thread::currentThread()->getId()); // Create a messages string text = (string) "Hello world! from thread " + threadIdStr; for (int ix = 0; ix < numMessages; ++ix) { std::auto_ptr<TextMessage> message(session->createTextMessage(text)); message->setIntProperty("Integer", ix); printf("Sent message #%d from thread %s\n", ix + 1, threadIdStr.c_str()); producer->send(message.get()); } } catch (CMSException& e) { e.printStackTrace(); } } private: void cleanup() { if (connection != NULL) { try { connection->close(); } catch (cms::CMSException& ex) { ex.printStackTrace(); } } // Destroy resources. try { delete destination; destination = NULL; delete producer; producer = NULL; delete session; session = NULL; delete connection; connection = NULL; } catch (CMSException& e) { e.printStackTrace(); } } }; class HelloWorldConsumer : public ExceptionListener, public MessageListener, public Runnable { private: CountDownLatch latch; CountDownLatch doneLatch; Connection* connection; Session* session; Destination* destination; MessageConsumer* consumer; long waitMillis; bool useTopic; bool sessionTransacted; std::string brokerURI; private: HelloWorldConsumer(const HelloWorldConsumer&); HelloWorldConsumer& operator=(const HelloWorldConsumer&); public: HelloWorldConsumer(const std::string& brokerURI, int numMessages, bool useTopic = false, bool sessionTransacted = false, int waitMillis = 30000) : latch(1), doneLatch(numMessages), connection(NULL), session(NULL), destination(NULL), consumer(NULL), waitMillis(waitMillis), useTopic(useTopic), sessionTransacted(sessionTransacted), brokerURI(brokerURI) { } virtual ~HelloWorldConsumer() { cleanup(); } void close() { this->cleanup(); } void waitUntilReady() { latch.await(); } virtual void run() { try { // Create a ConnectionFactory auto_ptr<ConnectionFactory> connectionFactory( ConnectionFactory::createCMSConnectionFactory(brokerURI)); // Create a Connection connection = connectionFactory->createConnection(); connection->start(); connection->setExceptionListener(this); // Create a Session if (this->sessionTransacted == true) { session = connection->createSession(Session::SESSION_TRANSACTED); } else { session = connection->createSession(Session::AUTO_ACKNOWLEDGE); } // Create the destination (Topic or Queue) if (useTopic) { destination = session->createTopic("TEST.FOO"); } else { destination = session->createQueue("TEST.FOO"); } // Create a MessageConsumer from the Session to the Topic or Queue consumer = session->createConsumer(destination); consumer->setMessageListener(this); std::cout.flush(); std::cerr.flush(); // Indicate we are ready for messages. latch.countDown(); // Wait while asynchronous messages come in. doneLatch.await(waitMillis); } catch (CMSException& e) { // Indicate we are ready for messages. latch.countDown(); e.printStackTrace(); } } // Called from the consumer since this class is a registered MessageListener. virtual void onMessage(const Message* message) { static int count = 0; try { count++; const TextMessage* textMessage = dynamic_cast<const TextMessage*> (message); string text = ""; if (textMessage != NULL) { text = textMessage->getText(); } else { text = "NOT A TEXTMESSAGE!"; } printf("Message #%d Received: %s\n", count, text.c_str()); } catch (CMSException& e) { e.printStackTrace(); } // Commit all messages. if (this->sessionTransacted) { session->commit(); } // No matter what, tag the count down latch until done. doneLatch.countDown(); } // If something bad happens you see it here as this class is also been // registered as an ExceptionListener with the connection. virtual void onException(const CMSException& ex AMQCPP_UNUSED) { printf("CMS Exception occurred. Shutting down client.\n"); ex.printStackTrace(); exit(1); } private: void cleanup() { if (connection != NULL) { try { connection->close(); } catch (cms::CMSException& ex) { ex.printStackTrace(); } } // Destroy resources. try { delete destination; destination = NULL; delete consumer; consumer = NULL; delete session; session = NULL; delete connection; connection = NULL; } catch (CMSException& e) { e.printStackTrace(); } } }; int main(int argc AMQCPP_UNUSED, char* argv[] AMQCPP_UNUSED) { activemq::library::ActiveMQCPP::initializeLibrary(); { std::cout << "=====================================================\n"; std::cout << "Starting the example:" << std::endl; std::cout << "-----------------------------------------------------\n"; // Set the URI to point to the IP Address of your broker. // add any optional params to the url to enable things like // tightMarshalling or tcp logging etc. See the CMS web site for // a full list of configuration options. // // http://activemq.apache.org/cms/ // // Wire Format Options: // ========================= // Use either stomp or openwire, the default ports are different for each // // Examples: // tcp://127.0.0.1:61616 default to openwire // tcp://127.0.0.1:61616?wireFormat=openwire same as above // tcp://127.0.0.1:61613?wireFormat=stomp use stomp instead // // SSL: // ========================= // To use SSL you need to specify the location of the trusted Root CA or the // certificate for the broker you want to connect to. Using the Root CA allows // you to use failover with multiple servers all using certificates signed by // the trusted root. If using client authentication you also need to specify // the location of the client Certificate. // // System::setProperty( "decaf.net.ssl.keyStore", "<path>/client.pem" ); // System::setProperty( "decaf.net.ssl.keyStorePassword", "password" ); // System::setProperty( "decaf.net.ssl.trustStore", "<path>/rootCA.pem" ); // // The you just specify the ssl transport in the URI, for example: // // ssl://localhost:61617 // std::string brokerURI = "failover:(tcp://localhost:61616" // "?wireFormat=openwire" // "&transport.useInactivityMonitor=false" // "&connection.alwaysSyncSend=true" // "&connection.useAsyncSend=true" // "?transport.commandTracingEnabled=true" // "&transport.tcpTracingEnabled=true" // "&wireFormat.tightEncodingEnabled=true" ")"; //============================================================ // set to true to use topics instead of queues // Note in the code above that this causes createTopic or // createQueue to be used in both consumer an producer. //============================================================ bool useTopics = true; bool sessionTransacted = false; int numMessages = 2000; long long startTime = System::currentTimeMillis(); HelloWorldProducer producer(brokerURI, numMessages, useTopics); HelloWorldConsumer consumer(brokerURI, numMessages, useTopics, sessionTransacted); // Start the consumer thread. Thread consumerThread(&consumer); consumerThread.start(); // Wait for the consumer to indicate that its ready to go. consumer.waitUntilReady(); // Start the producer thread. Thread producerThread(&producer); producerThread.start(); // Wait for the threads to complete. producerThread.join(); consumerThread.join(); long long endTime = System::currentTimeMillis(); double totalTime = (double)(endTime - startTime) / 1000.0; consumer.close(); producer.close(); std::cout << "Time to completion = " << totalTime << " seconds." << std::endl; std::cout << "-----------------------------------------------------\n"; std::cout << "Finished with the example." << std::endl; std::cout << "=====================================================\n"; } activemq::library::ActiveMQCPP::shutdownLibrary(); } // END SNIPPET: demo 从main()开始吧. 这样便简快速的实现了应用逻辑. 3,activemq的几种通信模式. 可以参考: http://shmilyaw-hotmail-com.iteye.com/blog/1897635 目前本人需要的是activemq-cpp的request-response 模式. 4,activemq-cpp的request-response 模式的应用. 服务器与客户端通信 数据的交互 和 确认. 以下是本人修改后的简单代码,bug可能存在,请指出. 复制两份,一份定义USE_COMSUMER 一份定义USE_PRODUCER 就可以生成. /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // START SNIPPET: demo #include <activemq/library/ActiveMQCPP.h> #include <decaf/lang/Thread.h> #include <decaf/lang/Runnable.h> #include <decaf/util/concurrent/CountDownLatch.h> #include <decaf/lang/Integer.h> #include <decaf/lang/Long.h> #include <decaf/lang/System.h> #include <activemq/core/ActiveMQConnectionFactory.h> #include <activemq/util/Config.h> #include <cms/Connection.h> #include <cms/Session.h> #include <cms/TextMessage.h> #include <cms/BytesMessage.h> #include <cms/MapMessage.h> #include <cms/ExceptionListener.h> #include <cms/MessageListener.h> #include <stdlib.h> #include <stdio.h> #include <iostream> #include <memory> #include <decaf/util/Random.h> using namespace activemq::core; using namespace decaf::util::concurrent; using namespace decaf::util; using namespace decaf::lang; using namespace cms; using namespace std; #define QUEUE_NAME "eventQueue" #define NAME_BYTE_LEN 16 class HelloWorldProducer : public ExceptionListener, public MessageListener, public Runnable { private: CountDownLatch latch; CountDownLatch doneLatch; Connection* connection; Session* session; Destination* destination; MessageProducer* producer; int numMessages; bool useTopic; bool sessionTransacted; std::string brokerURI; bool bReciveMessage; long waitMillis; private: HelloWorldProducer(const HelloWorldProducer&); HelloWorldProducer& operator=(const HelloWorldProducer&); public: HelloWorldProducer(const std::string& brokerURI, int numMessages, bool useTopic = false, bool sessionTransacted = false, long waitMillis=3000) : latch(1), doneLatch(numMessages), connection(NULL), session(NULL), destination(NULL), producer(NULL), numMessages(numMessages), useTopic(useTopic), sessionTransacted(sessionTransacted), brokerURI(brokerURI) , bReciveMessage(false), waitMillis(waitMillis) { } virtual ~HelloWorldProducer(){ cleanup(); } void close() { this->cleanup(); } void waitUntilReady() { latch.await(); } virtual void run() { try { // Create a ConnectionFactory auto_ptr<ConnectionFactory> connectionFactory( ConnectionFactory::createCMSConnectionFactory(brokerURI)); // Create a Connection connection = connectionFactory->createConnection(); connection->start(); // Create a Session if (this->sessionTransacted) { session = connection->createSession(Session::SESSION_TRANSACTED); } else { session = connection->createSession(Session::AUTO_ACKNOWLEDGE); } session = connection->createSession(); // Create the destination (Topic or Queue) if (useTopic) { destination = session->createTopic(QUEUE_NAME); } else { destination = session->createQueue(QUEUE_NAME); } // Create a MessageProducer from the Session to the Topic or Queue producer = session->createProducer(destination); producer->setDeliveryMode(DeliveryMode::NON_PERSISTENT); // Create the Thread Id String string threadIdStr = Long::toString(Thread::currentThread()->getId()); // Create a messages string text = (string) "Hello world! from thread " + threadIdStr; for (int ix = 0; ix < numMessages; ++ix) { std::auto_ptr<TextMessage> message(session->createTextMessage(text)); //关键消息... std::auto_ptr<Destination> tempDest(session->createTemporaryQueue()); //cms::Destination tempDest=session->createTemporaryTopic() ; MessageConsumer * responseConsumer = session->createConsumer(tempDest.get()); responseConsumer->setMessageListener(this);//监听... message->setCMSReplyTo(tempDest.get()); Random random; char buffer[NAME_BYTE_LEN]={0}; random.nextBytes((unsigned char *)buffer,NAME_BYTE_LEN); string correlationId=""; for(int i=0;i<NAME_BYTE_LEN;++i) { char ch[NAME_BYTE_LEN*2]={0}; sprintf(ch,"%02X",(unsigned char)buffer[i]); string str(ch); correlationId+=str; } message->setCMSCorrelationID(correlationId); message->setIntProperty("Integer", ix); printf("Producer Sent message #%d from thread %s\n", ix + 1, threadIdStr.c_str()); producer->send(message.get()); // Indicate we are ready for messages. latch.countDown(); // Wait while asynchronous messages come in. doneLatch.await(waitMillis); } } catch (CMSException& e) { printf("Producer run() CMSException \n" ); // Indicate we are ready for messages. latch.countDown(); e.printStackTrace(); } } // Called from the Producer since this class is a registered MessageListener. virtual void onMessage(const Message* message) { static int count = 0; try { count++; const TextMessage* textMessage = dynamic_cast<const TextMessage*> (message); //ActiveMQMessageTransformation //std::auto_ptr<TextMessage> responsemessage(session->createTextMessage()); //responsemessage->setCMSCorrelationID(textMessage->getCMSCorrelationID()); //responsemessage->getCMSReplyTo() string text = ""; if (textMessage != NULL) { text = textMessage->getText(); } else { text = "NOT A TEXTMESSAGE!"; } printf("Producer Message #%d Received: %s\n", count, text.c_str()); //producer.send } catch (CMSException& e) { printf("Producer onMessage() CMSException \n" ); e.printStackTrace(); } // Commit all messages. if (this->sessionTransacted) { session->commit(); } // No matter what, tag the count down latch until done. doneLatch.countDown(); } // If something bad happens you see it here as this class is also been // registered as an ExceptionListener with the connection. virtual void onException(const CMSException& ex AMQCPP_UNUSED) { printf("Producer onException() CMS Exception occurred. Shutting down client. \n" ); ex.printStackTrace(); exit(1); } private: void cleanup() { if (connection != NULL) { try { connection->close(); } catch (cms::CMSException& ex) { ex.printStackTrace(); } } // Destroy resources. try { delete destination; destination = NULL; delete producer; producer = NULL; delete session; session = NULL; delete connection; connection = NULL; } catch (CMSException& e) { e.printStackTrace(); } } }; class HelloWorldConsumer : public ExceptionListener, public MessageListener, public Runnable { private: CountDownLatch latch; CountDownLatch doneLatch; Connection* connection; Session* session; Destination* destination; MessageConsumer* consumer; MessageProducer *producer; long waitMillis; bool useTopic; bool sessionTransacted; std::string brokerURI; private: HelloWorldConsumer(const HelloWorldConsumer&); HelloWorldConsumer& operator=(const HelloWorldConsumer&); public: HelloWorldConsumer(const std::string& brokerURI, int numMessages, bool useTopic = false, bool sessionTransacted = false, int waitMillis = 30000) : latch(1), doneLatch(numMessages), connection(NULL), session(NULL), destination(NULL), consumer(NULL), producer(NULL), waitMillis(waitMillis), useTopic(useTopic), sessionTransacted(sessionTransacted), brokerURI(brokerURI) { } virtual ~HelloWorldConsumer() { cleanup(); } void close() { this->cleanup(); } void waitUntilReady() { latch.await(); } virtual void run() { try { // Create a ConnectionFactory auto_ptr<ConnectionFactory> connectionFactory( ConnectionFactory::createCMSConnectionFactory(brokerURI)); // Create a Connection connection = connectionFactory->createConnection(); connection->start(); connection->setExceptionListener(this); // Create a Session if (this->sessionTransacted == true) { session = connection->createSession(Session::SESSION_TRANSACTED); } else { session = connection->createSession(Session::AUTO_ACKNOWLEDGE); } // Create the destination (Topic or Queue) if (useTopic) { destination = session->createTopic(QUEUE_NAME); } else { destination = session->createQueue(QUEUE_NAME); } producer = session->createProducer(); producer->setDeliveryMode(DeliveryMode::NON_PERSISTENT); // Create a MessageConsumer from the Session to the Topic or Queue consumer = session->createConsumer(destination); consumer->setMessageListener(this); std::cout.flush(); std::cerr.flush(); // Indicate we are ready for messages. latch.countDown(); // Wait while asynchronous messages come in. doneLatch.await(); } catch (CMSException& e) { printf("Consumer onException() CMS Exception occurred. Shutting down client. \n" ); // Indicate we are ready for messages. latch.countDown(); e.printStackTrace(); } } // Called from the consumer since this class is a registered MessageListener. virtual void onMessage(const Message* message) { static int count = 0; try { count++; // Create the Thread Id String string threadIdStr = Long::toString(Thread::currentThread()->getId()); static bool bPrintf=true; if(bPrintf) { bPrintf=false; printf("consumer Message threadid: %s\n", threadIdStr.c_str()); } string strReply="consumer return xxx,ThreadID="+threadIdStr; const TextMessage* textMessage = dynamic_cast<const TextMessage*> (message); if(NULL==textMessage) { printf("NULL==textMessage", message->getCMSType().c_str()); //const cms::MapMessage* mapMsg = dynamic_cast<const cms::MapMessage*>(message); //if(mapMsg) //{ // // std::vector<std::string> elements = mapMsg->getMapNames(); // std::vector<std::string>::iterator iter = elements.begin(); // for(; iter != elements.end() ; ++iter) // { // std::string key = *iter; // cms::Message::ValueType elementType = mapMsg->getValueType(key); // string strxxx; // int cc=0; // switch(elementType) { // case cms::Message::BOOLEAN_TYPE: // //msg->setBoolean(key, mapMsg->getBoolean(key)); // break; // case cms::Message::BYTE_TYPE: // //msg->setByte(key, mapMsg->getByte(key)); // break; // case cms::Message::BYTE_ARRAY_TYPE: // //msg->setBytes(key, mapMsg->getBytes(key)); // break; // case cms::Message::CHAR_TYPE: // //msg->setChar(key, mapMsg->getChar(key)); // break; // case cms::Message::SHORT_TYPE: // //msg->setShort(key, mapMsg->getShort(key)); // break; // case cms::Message::INTEGER_TYPE: // //msg->setInt(key, mapMsg->getInt(key)); // break; // case cms::Message::LONG_TYPE: // //msg->setLong(key, mapMsg->getLong(key)); // break; // case cms::Message::FLOAT_TYPE: // //msg->setFloat(key, mapMsg->getFloat(key)); // break; // case cms::Message::DOUBLE_TYPE: // //msg->setDouble(key, mapMsg->getDouble(key)); // break; // case cms::Message::STRING_TYPE: // //msg->setString(key, mapMsg->getString(key)); // strxxx=mapMsg->getString(key); // cc=1; // break; // default: // break; // } // } //} return; } std::auto_ptr<TextMessage> responsemessage(session->createTextMessage(strReply)); responsemessage->setCMSCorrelationID(textMessage->getCMSCorrelationID()); string text = ""; if (textMessage != NULL) { text = textMessage->getText(); } else { text = "NOT A TEXTMESSAGE!"; } int nProPerty=textMessage->getIntProperty("Integer"); printf("consumer Message #%d Received: %s,nProPerty[%d]\n", count, text.c_str(),nProPerty); const cms::Destination* destSend=textMessage->getCMSReplyTo(); if(destSend) { this->producer->send(destSend,responsemessage.get()); printf("consumer Message #%d send: %s\n", count, strReply.c_str()); } } catch (CMSException& e) { printf("Consumer onMessage() CMS Exception occurred. Shutting down client. \n" ); e.printStackTrace(); } // Commit all messages. if (this->sessionTransacted) { session->commit(); } // No matter what, tag the count down latch until done. //doneLatch.countDown(); } // If something bad happens you see it here as this class is also been // registered as an ExceptionListener with the connection. virtual void onException(const CMSException& ex AMQCPP_UNUSED) { printf("Consumer onException() CMS Exception occurred. Shutting down client. \n" ); //printf("CMS Exception occurred. Shutting down client.\n"); ex.printStackTrace(); exit(1); } private: void cleanup() { if (connection != NULL) { try { connection->close(); } catch (cms::CMSException& ex) { ex.printStackTrace(); } } // Destroy resources. try { delete destination; destination = NULL; delete consumer; consumer = NULL; delete session; session = NULL; delete connection; connection = NULL; } catch (CMSException& e) { e.printStackTrace(); } } }; int main(int argc AMQCPP_UNUSED, char* argv[] AMQCPP_UNUSED) { //if(argc<2) //{ // printf("argc<2\r\n"); // return 0; //} activemq::library::ActiveMQCPP::initializeLibrary(); { std::cout << "=====================================================\n"; std::cout << "Starting the example:" << std::endl; std::cout << "-----------------------------------------------------\n"; // Set the URI to point to the IP Address of your broker. // add any optional params to the url to enable things like // tightMarshalling or tcp logging etc. See the CMS web site for // a full list of configuration options. // // http://activemq.apache.org/cms/ // // Wire Format Options: // ========================= // Use either stomp or openwire, the default ports are different for each // // Examples: // tcp://127.0.0.1:61616 default to openwire // tcp://127.0.0.1:61616?wireFormat=openwire same as above // tcp://127.0.0.1:61613?wireFormat=stomp use stomp instead // // SSL: // ========================= // To use SSL you need to specify the location of the trusted Root CA or the // certificate for the broker you want to connect to. Using the Root CA allows // you to use failover with multiple servers all using certificates signed by // the trusted root. If using client authentication you also need to specify // the location of the client Certificate. // // System::setProperty( "decaf.net.ssl.keyStore", "<path>/client.pem" ); // System::setProperty( "decaf.net.ssl.keyStorePassword", "password" ); // System::setProperty( "decaf.net.ssl.trustStore", "<path>/rootCA.pem" ); // // The you just specify the ssl transport in the URI, for example: // // ssl://localhost:61617 // std::string brokerURI = "failover:(tcp://192.168.10.143:61616" // "?wireFormat=openwire" // "&transport.useInactivityMonitor=false" // "&connection.alwaysSyncSend=true" // "&connection.useAsyncSend=true" // "?transport.commandTracingEnabled=true" // "&transport.tcpTracingEnabled=true" // "&wireFormat.tightEncodingEnabled=true" ")"; //============================================================ // set to true to use topics instead of queues // Note in the code above that this causes createTopic or // createQueue to be used in both consumer an producer. //============================================================ bool useTopics = false; bool sessionTransacted = true; int numMessages = 1; bool useConsumer=true; bool useProducer=true; //int nSet=atoi(argv[1]); //if(1==nSet) //{ //#define USE_COMSUMER //} //else //{ //#define USE_PRODUCER // //} long long startTime = System::currentTimeMillis(); #ifdef USE_PRODUCER printf("当前 USE_PRODUCER \r\n"); int numProducerMessages = 30; int nThreadNumber=10; vector<HelloWorldProducer *> vHelloWorldProducer; for(int i=0;i<nThreadNumber;++i) { HelloWorldProducer * producerTemp=new HelloWorldProducer(brokerURI, numProducerMessages, useTopics); vHelloWorldProducer.push_back(producerTemp); } #endif #ifdef USE_COMSUMER printf("当前 USE_COMSUMER \r\n"); HelloWorldConsumer consumer(brokerURI, numMessages, useTopics, sessionTransacted); // Start the consumer thread. Thread consumerThread(&consumer); consumerThread.start(); // Wait for the consumer to indicate that its ready to go. consumer.waitUntilReady(); #endif #ifdef USE_PRODUCER // Start the producer thread. vector<Thread *> vThread; for(int i=0;i<nThreadNumber;++i) { HelloWorldProducer & ProducerTemp=*vHelloWorldProducer[i]; Thread * threadTemp=new Thread(&ProducerTemp); vThread.push_back(threadTemp); threadTemp->start(); ProducerTemp.waitUntilReady(); } for(int i=0;i<vThread.size();++i) { Thread * threadTemp=vThread[i]; //threadTemp->join(); } while(1) { Thread::sleep(10); } //Thread producerThread1(&producer1); //producerThread1.start(); //producer1.waitUntilReady(); //Thread producerThread2(&producer2); //producerThread2.start(); //producer2.waitUntilReady(); //Thread producerThread3(&producer3); //producerThread3.start(); //producer3.waitUntilReady(); #endif #ifdef USE_PRODUCER // Wait for the threads to complete. //producerThread1.join(); //producerThread2.join(); //producerThread3.join(); #endif #ifdef USE_COMSUMER consumerThread.join(); #endif long long endTime = System::currentTimeMillis(); double totalTime = (double)(endTime - startTime) / 1000.0; #ifdef USE_PRODUCER //producer1.close(); //producer2.close(); //producer3.close(); for(int i=0;i<vHelloWorldProducer.size();++i) { HelloWorldProducer * ProducerTemp=vHelloWorldProducer[i]; ProducerTemp->close(); if(ProducerTemp) { delete ProducerTemp; ProducerTemp=NULL; } } #endif #ifdef USE_COMSUMER consumer.close(); #endif std::cout << "Time to completion = " << totalTime << " seconds." << std::endl; std::cout << "-----------------------------------------------------\n"; std::cout << "Finished with the example." << std::endl; std::cout << "=====================================================\n"; } activemq::library::ActiveMQCPP::shutdownLibrary(); return 0; } // END SNIPPET: demo 程序运行结果: 关于activemq-cpp 的Message 消息转换. activemq-cpp 中的转换ActiveMQMessageTransformation.transformMessage 中是有相应的实现. //////////////////////////////////////////////////////////////////////////////// bool ActiveMQMessageTransformation::transformMessage(cms::Message* message, ActiveMQConnection* connection, Message** amqMessage) { if (message == NULL) { throw NullPointerException(__FILE__, __LINE__, "Provided source cms::Message pointer was NULL"); } if (amqMessage == NULL) { throw NullPointerException(__FILE__, __LINE__, "Provided target commands::Message pointer was NULL"); } *amqMessage = dynamic_cast<Message*>(message); if (*amqMessage != NULL) { return false; } else { if (dynamic_cast<cms::BytesMessage*>(message) != NULL) { cms::BytesMessage* bytesMsg = dynamic_cast<cms::BytesMessage*>(message); bytesMsg->reset(); ActiveMQBytesMessage* msg = new ActiveMQBytesMessage(); msg->setConnection(connection); try { for (;;) { // Reads a byte from the message stream until the stream is empty msg->writeByte(bytesMsg->readByte()); } } catch (cms::MessageEOFException& e) { // if an end of message stream as expected } catch (cms::CMSException& e) { } *amqMessage = msg; } else if (dynamic_cast<cms::MapMessage*>(message) != NULL) { cms::MapMessage* mapMsg = dynamic_cast<cms::MapMessage*>(message); ActiveMQMapMessage* msg = new ActiveMQMapMessage(); msg->setConnection(connection); std::vector<std::string> elements = mapMsg->getMapNames(); std::vector<std::string>::iterator iter = elements.begin(); for(; iter != elements.end() ; ++iter) { std::string key = *iter; cms::Message::ValueType elementType = mapMsg->getValueType(key); switch(elementType) { case cms::Message::BOOLEAN_TYPE: msg->setBoolean(key, mapMsg->getBoolean(key)); break; case cms::Message::BYTE_TYPE: msg->setByte(key, mapMsg->getByte(key)); break; case cms::Message::BYTE_ARRAY_TYPE: msg->setBytes(key, mapMsg->getBytes(key)); break; case cms::Message::CHAR_TYPE: msg->setChar(key, mapMsg->getChar(key)); break; case cms::Message::SHORT_TYPE: msg->setShort(key, mapMsg->getShort(key)); break; case cms::Message::INTEGER_TYPE: msg->setInt(key, mapMsg->getInt(key)); break; case cms::Message::LONG_TYPE: msg->setLong(key, mapMsg->getLong(key)); break; case cms::Message::FLOAT_TYPE: msg->setFloat(key, mapMsg->getFloat(key)); break; case cms::Message::DOUBLE_TYPE: msg->setDouble(key, mapMsg->getDouble(key)); break; case cms::Message::STRING_TYPE: msg->setString(key, mapMsg->getString(key)); break; default: break; } } *amqMessage = msg; } else if (dynamic_cast<cms::ObjectMessage*>(message) != NULL) { cms::ObjectMessage* objMsg = dynamic_cast<cms::ObjectMessage*>(message); ActiveMQObjectMessage* msg = new ActiveMQObjectMessage(); msg->setConnection(connection); msg->setObjectBytes(objMsg->getObjectBytes()); *amqMessage = msg; } else if (dynamic_cast<cms::StreamMessage*>(message) != NULL) { cms::StreamMessage* streamMessage = dynamic_cast<cms::StreamMessage*>(message); streamMessage->reset(); ActiveMQStreamMessage* msg = new ActiveMQStreamMessage(); msg->setConnection(connection); try { while(true) { cms::Message::ValueType elementType = streamMessage->getNextValueType(); int result = -1; std::vector<unsigned char> buffer(255); switch(elementType) { case cms::Message::BOOLEAN_TYPE: msg->writeBoolean(streamMessage->readBoolean()); break; case cms::Message::BYTE_TYPE: msg->writeBoolean(streamMessage->readBoolean()); break; case cms::Message::BYTE_ARRAY_TYPE: while ((result = streamMessage->readBytes(buffer)) != -1) { msg->writeBytes(&buffer[0], 0, result); buffer.clear(); } break; case cms::Message::CHAR_TYPE: msg->writeChar(streamMessage->readChar()); break; case cms::Message::SHORT_TYPE: msg->writeShort(streamMessage->readShort()); break; case cms::Message::INTEGER_TYPE: msg->writeInt(streamMessage->readInt()); break; case cms::Message::LONG_TYPE: msg->writeLong(streamMessage->readLong()); break; case cms::Message::FLOAT_TYPE: msg->writeFloat(streamMessage->readFloat()); break; case cms::Message::DOUBLE_TYPE: msg->writeDouble(streamMessage->readDouble()); break; case cms::Message::STRING_TYPE: msg->writeString(streamMessage->readString()); break; default: break; } } } catch (cms::MessageEOFException& e) { // if an end of message stream as expected } catch (cms::CMSException& e) { } *amqMessage = msg; } else if (dynamic_cast<cms::TextMessage*>(message) != NULL) { cms::TextMessage* textMsg = dynamic_cast<cms::TextMessage*>(message); ActiveMQTextMessage* msg = new ActiveMQTextMessage(); msg->setConnection(connection); msg->setText(textMsg->getText()); *amqMessage = msg; } else { *amqMessage = new ActiveMQMessage(); (*amqMessage)->setConnection(connection); } ActiveMQMessageTransformation::copyProperties(message, dynamic_cast<cms::Message*>(*amqMessage)); } return true; } 5,activemq 的activemq broker cluster (activemq 集群). 可以参考: http://bh-keven.iteye.com/blog/1617788 http://blog.csdn.net/jason5186/article/details/18702523 6,activemq.xml 中的配置和activemq Connection URIS 配置 Index> Apache.NMS.ActiveMQ> ActiveMQ URI Configuration http://activemq.apache.org/nms/activemq-uri-configuration.html http://activemq.apache.org/tcp-transport-reference.html 是有相应介绍,但需要花一些时间去读. //7,wireFormat=openwire 的几种方式.的优缺点. //openwire,amqp,stomp,mqtt,ws

优秀的个人博客,低调大师

2018年Kotlin学习资料汇总

目录 awesome-kotlin-android 关于 目录 开源库 框架 DSL 扩展 UI 通用库 动画 Toolbar 按钮 依赖注入 数据绑定 代理 数据库 网络 日志 函数式编程 下载 图片 拍照 工具 其他 完整 app DEMO 书籍 视频 ​ 开源库 框架 KBinding - 使用kotlin实现的Android MVVM框架 Kotlin-Android-Template - 快速生成MVP 架构的项目模板 android-clean-architecture-boilerplate - clean 框架模板 DSL anko - JetBrains 官方为Android编写的 DSL,旨在令开发 Android 更快更简单 android-drawable-dsl - 通过 kotlin 构造 drawable 而不是 XML 的 DSL MaterialDrawerKt - 不使用 XML 创建 Material Design 导航抽屉 扩展 android-ktx - google 开源的 Kotlin 扩展插件库,在 Android 框架和 Support Library 上提供相应 API 层,帮助开发者更自然编写 Kotlin 代码 KAndroid - 轻量级Kotlin 扩展插件库 kotlin-jetpack 有用的扩展方法集合 kotlin-koi - 又一个轻量级Kotlin 扩展插件库 UI 通用库 anvil - 一个受React启发的Android的最小UI库 动画 Konfetti - 轻量五彩纸屑粒子系统 效果图: transitioner - 动态、简单的View场景切换动画 效果图: Toolbar JellyToolbar - Yalantis出品,必属精品!炫酷 toolbar 实现 效果图: 按钮 Stepper-Touch - Material Design设计风格的触摸步进器 效果图: 依赖注入

优秀的个人博客,低调大师

EduSoho:免费部署在线学习平台

版权声明:转载请注明出处:http://blog.csdn.net/dajitui2024 https://blog.csdn.net/dajitui2024/article/details/79396608 EduSoho帮助培训机构和个人以最低成本、最快速度建立自己的在线教学网站,采用PHP 5开发,使用mysql数据库。 框架使用Symfony2.3 的视图层 + 自主研发的服务容器框架。更多帮助文档:http://www.edusoho.com/helphttp://www.qiqiuyu.com/ 1、基础配置: 官方推荐的配置是LNMP,即Linux+Nginx+MySQL+PHP 选择操作系统(Linux) 推荐使用Ubuntu,Fedora,CentOS,Gentoo。 选择Web服务器(Nginx或Apache2) Web服务器,官方推荐:Nginx或Apache2。关于Nginx:下载地址: http://nginx.org/en/download.html版本推荐: 1.0以上关于Apache2:下载地址: http://httpd.apache.org/download.cgi推荐版本: 2.0以上 选择MySQL数据库 MySQL数据库推荐版本:5.0以上。下载地址:http://www.mysql.com/downloads 选择PHP版本 版本: >= 5.5.0下载地址:http://cn2.php.net/downloads.php 注意:1. Linux 下需要关闭SeLinux ,不然安装完成页面会空白2.Nginx.conf中一定要配置client_max_body_size, 不然上传大文会卡住时 详细配置文档指导: Ubuntu14.04+Nginx+PHP+MySQL+EduSoho[推荐-标准环境-文档]Ubuntu 14.04+Apache+PHP+MySQL+EduSoho[文档]Ubuntu 12.04/14.04 以及 CentOS 6.x 一键安装EduSoho [推荐 - 快捷安装]Ubuntu14.04,使用Docker一键安装EduSohoCentOS 6.x + Nginx + PHP + MySQL + EduSoho[文档]CentOS 6.x + Apache+ PHP + MySQL + EduSoho[文档]CentOS 7 + Nginx + PHP + MySql + EduSohoCentOS 7 + Apache + PHP + MySql + EduSoho已预装EduSoho的Ubuntu 14.04 VMWare虚拟机AMH+LAMP安装EduSohoAMH+LNMP安装EduSohoWDCP + CentOS 6.x + EduSoho + Nginx

优秀的个人博客,低调大师

算法学习之路|日期问题

小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。 比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。 给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗? 输入 一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9) 输出 输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。 样例输入 02/03/04 样例输出 2002-03-04 2004-02-03 2004-03-02 资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 1000ms 请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。 注意: main函数需要返回0; 只使用ANSI C/ANSI C++ 标准; 不要调用依赖于编译环境或操作系统的特殊函数。 所有依赖的函数必须明确地在源文件中 #include 不能通过工程设置而省略常用头文件。 提交程序时,注意选择所期望的语言类型和编译器类型 解题思路: 把每一部分的功能都分开了。 先判断天数,月份,年数是否正确。 注意: 瑞年以及不是瑞年要当心。 #include<iostream> using namespace std; int day(int month,int year); bool isrui(int year);//这两个包用于给其他包用 //剩下的包只给main函数用 bool isyear(int year){ if(year<=2059&&year>=1960){ return true; } else{ return false; } } bool ismonth(int month){ if(month<=12&&month>=1){ return true; } else{ return false; } } bool isday(int year,int month,int yourday){ if(yourday>day(month,year)||yourday==0){ return false; } else return true; } bool isrui(int year){ if ((year%4==0&&year%100!=0)||year%400==0){ return true; } else{ return false; } } int day(int month,int year){ if(month==0){ return 0; } if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){ return 31; } else if(month==2&&isrui(year)){ return 29; } else if(month==2&&!isrui(year)){ return 28; } else{ return 30; } } void abc(int A,int B,int C){//核心函数 if(A<60) A+=2000; else if(A>=60) A+=1900; if(isyear(A)){ if(ismonth(B)){ if(isday(A, B, C)){ printf("%d-%02d-%02d\n",A,B,C); } } } } int main(){ int A,B,C; scanf("%d/%d/%d",&A,&B,&C); abc(A,B,C); abc(C,A,B); abc(C,B,A); }

优秀的个人博客,低调大师

python-opencv学习笔记(二)

图像与原始字节之间的转换:从概念上,一个字节能表示0到255的整数,通常一个像素每个通道由一个字节表示。一个OpenCV图像是.array类型的二维或者三维数组。8位的灰度图像是一个含有字节值得二维数组。一个24位的BGR图像是一个三维数组,也包含了字节值,可以使用表达式访问这些值,如image[0,0]或者image[0,0,0]。第一个值表示y坐标,第二个值表示x坐标,第三个值为颜色通道。还可以使用image.item((0,0))或image.setitem((0,0),128)来访问像素和对像素进行操作。若一幅图像的每个通道为8位,则可以将其显式转换为标准的移位Python bytearray格式: byteArray=bytearray(image) bytearray含有恰当顺序的字节,可以通过显式转换和重构,得到numpy.array形式的图像: grayImage=numpy.array(grayByteArray).reshape(height,width) bgrImage=numpy.array(bgrByteArray).reshape(height,width,3) 下面介绍一个将含有随机字节bytearray转换为灰度图像和BGR图像: import cv2 import numpy as np import os randomByteArray=bytearray(os.urandom(120000)) flatNumpyArray=np.array(randomByteArray) grayImage=flatNumpyArray.reshape(300,400) cv2.imwrite('RandomGray.png',grayImage) bgrImage=flatNumpyArray.reshape(100,400,3) cv2.imwrite('RandomColor.png',bgrImage) 结果产生灰度图:和彩色图像:使用numpy.random.randint(0,256,120000).reshape(300,400)也可以并更加高效地生成Numpy数组。使用numpy.array访问图像数据:y.array结构针对数组操作有很好地优化,允许(bulk)操作。.array操作再OpenCV图像处理中会很方便使用,如对BGR图像的某一像素点进行操作,转换为白色像素点: import cv2 import numpy as np img=cv2.imread('time.jpg') img[0,0]=[255,255,255] cv2.imshow('1',img) cv2.waitKey() 用numpy.array函数来转换数组比普通的Python数组转换要快得多。方法: import cv2 import numpy as np img=cv2.imread('time.jpg') print(img.item(150,120,0)) img.itemset((150,120,0),255) print(img.item((150,120,0))) 使用numpy.array的原因:numpy.array处理这类问题进过很好地优化;通过Numpy的方法代码可读性更强。下面是对通道的操作,指定某一通道的所有值置为0: import cv2 import numpy as np img=cv2.imread('time.jpg') img[:,:,1]=0 cv2.imshow('1',img) cv2.waitKey() 注意:通过循环操作来处理Python数组的效率非常低,尽量避免;使用数组索引可以高效地操作像素,像素操作是一个高代价的低效操作,特别是在处理视频图像时,可用索引来解决这个问题。通过NumPy数组的索引访问原始图像:设置感兴趣区域(Region Of Interest ,ROI): import cv2 import numpy as np img=cv2.imread('time.jpg') my_roi=img[0:100,0:100] img[300:400,300:400]=my_roi cv2.imshow('1',img) cv2.waitKey() 要确保这两个区域大小相同。numpy.array获取图像的属性: import cv2 import numpy as np img=cv2.imread('time.jpg') print(img.shape) print(img.size) print(img.dtype) 结果: (1080, 1920, 3) 6220800 uint8 其中三个属性为:Shape:NumPy返回包含宽度,高度和通道数的数组,在调试图像类型调试时有用,如果图像是单色或灰度的,将不包含通道值。Size:该属性是指图像像素的大小Dtype:该属性会得到图像的数据类型(通常为一个无符号整数型的变量和该类型占的位数,比如uint8类型)

优秀的个人博客,低调大师

python-opencv学习笔记(三)

Opencv提供了VideoCapture类和VideoWriter类来支持各种格式的视频文件。在到达视频文件末尾之前VideoCapture类可以通过read()函数来获取新的帧,每一帧是一幅BGR格式的图像。可将一幅传递给VideoWriter类的write()函数,该函数会将这幅图像加到VideoWriter类所指向的文件中下面是一个例子,读取MP4文件,并采用YUV颜色编码将其写入另一帧中: import cv2 videoCapture=cv2.VideoCapture('myvid.mp4') fps=videoCapture.get(cv2.CAP_PROP_FPS) size=(int(videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))) videoWriter=cv2.VideoWriter( 'MyOutPut.avi',cv2.VideoWriter_fourcc('I','4','2','0'),fps,size ) success,frame=videoCapture.read() while success: videoWriter.write(frame) success,frame=videoCapture.read() 要注意:必须要为VideoWriter类的构造函数指定视频文件名,这个文件名对应的文件若存在,会被覆盖。也必须指定视频编解码器。编解码器的可能性根据系统不同而不同: cv2.VideoWriter_fourcc(‘I’,‘4’,‘2’,‘0’):该选项是一个未压缩的YUV颜色编码,是4:2:0色度子采集。这种编码兼容性较好,但文件较大,扩展名为.avi cv2.VideoWriter_foucc('P','I','M','I'):该选项是MPEG-1编码类型,扩展名为.avi cv2.VideoWriter_foucc('X','V','I','D'):该选项是MPEG-4编码类型,如果希望得到的视频大小为平均值,推荐使用此选项,文件扩展名.avi cv2.VideoWriter_foucc('T','H','E','O'):该选项Ogg Vorbis,文件扩展名应为.ogv。 cv2.VideoWriter_foucc('F','L','V','I'):该选项是一个Flash视频,文件扩展名应为.flv帧速率和帧大小也应该指定,因为需要从另一个视频复制视频帧,这些属性可以通过VideoCapture类的get()函数得到。 捕获摄像头帧:VideoCapture类可以获得摄像头的帧流。但对摄像头而言,通常不是用视频的文件名来构造VideoCapture类,而是需要传递摄像头的设备索引(device index)。 import cv2 cameraCapture=cv2.VideoCapture(0) fps=30 size=(int (cameraCapture.get(cv2.CAP_PROP_FRAME_WIDTH)), int (cameraCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))) videoWriter=cv2.VideoWriter( 'MyOutPutVid.avi',cv2.VideoWriter_fourcc('I','4','2','0'), fps,size ) success,frame=cameraCapture.read() numFramesRemaining=10*fps-1 while success and numFramesRemaining>0: videoWriter.write(frame) success,frame=cameraCapture.read() numFramesRemaining -=1 cameraCapture.release() 但VideoCapture类的get()方法不能返回摄像头速率的准确值,总是返回0。为了针对摄像头创建合适的VideoWriter类,要么对帧数率做出假设,要么使用计时器来测量,后一种更加好一些。摄像头的数目和顺序系统决定。但OpenCV没有提供任何查询摄像头数目和属性的方法。如果使用无效索引构造了VideoCapture类,就不会得到帧,VideoCapture的read()函数会返回(false,None)。为了不让read()函数从没有正确打开的VideoCapture类中获取数据,可在执行该函数之后使用VideoCa.isOpened方法一个判断,该方法返回一个Boolean值。当需要同步一组摄像头或多头(multihead)摄像头(例如立体摄像头或kinect)时,read()不合适,可用grab()和retrive()代替,可使用以下代码: success0=cameraCaputer0.grad() success1=cameraCapture1.grad() if success0 and success1: frame0=cameraCapture0.retrive() frame1=cameraCapture1.retrive()

优秀的个人博客,低调大师

Python-OpenCV学习笔记(六)

颜色色域: 灰度色域,除去彩色信息将其转换成灰阶,灰度色域对中间处理有效,如人脸检测 BGR :每个像素点都是有一个三元数组来表示-HSV,H(Hue)色调,S(saturation)饱和度,V(Value)亮度 傅里叶变换:傅里叶变换可以区分图像哪里变换强,哪里变换不强,标记噪声区域,感兴趣区域,前景和背景等。在Python的Numpy中有快速傅里叶变换(FFT)包,其中包含了fft2()函数。图像的幅度谱是另一种图像,幅度谱呈现了原始图像在变化方面的一种表示:把一幅图像中明亮的像素放到图像中间,然后逐渐变暗,在边缘上的罪案,可以发现亮暗像素的分布及百分比。高通滤波器:例子: import cv2 import numpy as np from scipy import ndimage kernel_3x3 = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]]) kernel_5x5 = np.array([[-1, -1, -1, -1, -1], [-1, 1, 2, 1, -1], [-1, 2, 4, 2, -1], [-1, 1, 2, 1, -1], [-1, -1, -1, -1, -1]]) img = cv2.imread("time.jpg", 0) k3 = ndimage.convolve(img, kernel_3x3) k5 = ndimage.convolve(img, kernel_5x5) blurred = cv2.GaussianBlur(img, (17,17), 0) g_hpf = img - blurred cv2.imshow("3x3", k3) cv2.imshow("5x5", k5) cv2.imshow("g_hpf", g_hpf) cv2.waitKey() cv2.destroyAllWindows() 导入模块后,定义一个3x3和5x5的核,然后读入以灰度的形式读入图像,因为NumPy的卷积只能是一维的用SCiPy的convolve()函数来解决。边缘检测:Opencv提供了许多边缘滤波函数,包括Laplacian(),Sobel()以及Scharr()。这些函数都会将非边缘区域转为黑色,将边缘区域转换为白色或其他颜色。但缺点是容易将噪声错误地识别为边缘。所以之前一般加一些滤波器。创建filters.py import cv2 import numpy as np import scipy.interpolate def strokeEdges(src ,dst ,blurKsize=7,edgeKsize=5): if blurKsize>=3: blurredSrc=cv2.medianBlur(src,blurKsize) graySrc=cv2.cvtColor(blurredSrc,cv2.COLOR_BGR2GRAY) else: graySrc=cv2.cvtColor(src,cv2.COLOR_BGR2GRAY) cv2.Laplacian(graySrc,cv2.CV_8U,graySrc,ksize=edgeKsize) normalizedInverseAlpha=(1.0/255)*(255-graySrc) channels=cv2.split(src) for channel in channels: channel[:]=channel*normalizedInverseAlpha cv2.merge(channels,dst) Canny边缘检测:Canny边缘检测算法复杂,有五个步骤,即使用高斯滤波器对图像进行去噪,计算梯度,在边缘上使用非最大抑制(NMS),在检测到的边缘上使用双阈值去除假阳性(false positive),最后还会分析所有边缘及其之间的连接,,以保留真正的边缘并消除不明显的边缘。 import cv2 import numpy as np img=cv2.imread("time.jpg",0) cv2.imwrite("canny.jpg",cv2.Canny(img,200,300)) cv2.imshow("canny",cv2.imread("canny.jpg")) cv2.waitKey() cv2.destroyAllWindows() 轮廓检测: import cv2 import numpy as np img = np.zeros((200, 200), dtype=np.uint8) img[50:150, 50:150] = 255 ret, thresh = cv2.threshold(img, 127, 255, 0) image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) img = cv2.drawContours(color, contours, -1, (0,255,0), 2) cv2.imshow("contours", color) cv2.waitKey() cv2.destroyAllWindows() 代码先创造了一个200x200大小的黑色空白图像,接着在图像的中央放置一个白色方块,用到了np数组在切片上赋值的功能。接下来对对图像进行二值化操作,然后调用findContours()函数。该函数有三个参数:输入图像,层次类型和轮廓逼近方法。这个函数会修改输入图像,因此建议使用原始图像的一份拷贝(通过img.copy()来作为输入图像)。由函数返回的层次树相当重要:cv2.RETR_TREE参数会得到图形中的轮廓的整体层次结构,以此来建立轮廓之间的“关系”。如果只想用到最外面的轮廓,可以用到cv2.RETR_EXTERNAL。这对消除包含在其他轮廓中的轮廓有用。findContours()函数有三个返回值:修改后的图像,图像轮廓以及层次

优秀的个人博客,低调大师

Python-OpenCV学习笔记(五)

使用managers.CaptureManager提取视频流CaptureManager类能对异性差异进行抽象,并提供了更加高级的接口从获取流中分配图像,再将图像分配到一个或多个输出中(如图像文件、视频文件或窗口)。在VideoCapture类中初始化CaptureManager类,在应用程序主循环的每一次迭代中通常应调用CaptureManager中的enterFrame()和exitFrame()函数。在调用enterFrame()和exitFrame()函数之间,应用程序可能会设定通道属性并获取帧属性。通道属性的初始值为0.只有在多台摄像头的情况下,通道属性的初始值非0,。帧属性是调用enterFrame()函数时与当前通道状态对应的图像。可能会经常调用CapTureManager类的writeImage(),startWritingVideo()和stopWritingVideo()函数。在调用exitFrame()函数之前,会有延迟写入文件。并且,在调用existFrame()函数过程中,帧属性可能会在窗口中显示,这取决于应用程序代码是将WindowManager类作为CaptureManager的构造函数参数还是设置previewWindowManager属性。如果应用程序代码处理了帧属性,那么在记录文件和窗口中会有所体现。CaptureManager类有一个称为shouldMirrorPreview的构造函数参数和属性,如果想要帧在窗口中镜像,但不记录在文件中,可将shouldMirrorPreciew设置为True。Opencv不能为摄像头提供准确的帧速率。解决这个问题的方法是通过帧计数器和Python标准的time.time()函数来估计帧数率。创建一个名为managers.py,该文件包含了CaptureM的实现,这各实现结果很长分成几段,先导入包、构造函数和属性: import cv2 import numpy import time class CaptureManager(object): def __init_(self,capture,previewWindowManager=None,shouldMirrorPreview=False): self.previewWindowManager=previewWindowManager self.shouldMirrorPreview=shouldMirrorPreview self._capture=capture self._channel=0 self._enteredFrame=False self._frame=None self._imageFilename=None self._videoFilename=None self._videoEncoding=None self._videoWriter=None self._startTime=None self._framesElapsed=numpy.long(0) self._fpsEstimate=None def channel(self): return self._channel def frame(self): if self._enteredFrame and self._frame is None: _,self._frame=self._capture.retyieve() return self._frame def isWritingImage(self): return self._imageFilename is not None def isWritingVideo(self): return self._videoFilename is not None 大多数成员变量为非公有变量,这类变量名前会加一个下划线进行标识。这些非公有变量与当前帧的状态以及文件写入操作有关。Python没有石油成员变量的概念,通常在变量前面加单/双下划线来表示私有变量。通常在Python中,以单下划线开始的成员变量称为保护变量,而异双下划线开始的变量称为私有成员变量。 def enterFrame(self): assert not self._enteredFrame if self._capture is not None: self._enteredFrame=self._capture.grab() def exitFrame(self): if self.frame is None: self._enteredFrame=False return if self._enteredFrame==0: self._startTime=time.time() else: timeElapsed=time.time()-self._startTime self._fpsEstimate=self._framesElapsed/timeElapsed self._framesElapsed+=1 if self.previewWindowManager is not None: if self.shouldMirrorPreview: mirroredFrame=numpy.fliplr(self._frame).copy() self.previewWindowManager.show(mirroredFrame) else: self.previewWindowManager.show(self._frame) if self.isWritingImage: cv2.imwrite(self._imageFilename,self._frame) self._imageFilename=None self._videoWriter() self._frame=None self._enteredFrame=False enterFrame()的实现只能(同步)获取一帧,而且会推出从一个通道获取,以便随后能从变量frame中读取。exitFrame()函数可以从当前通道获取图像、估计帧速率、通过窗口管理器显示图像,执行暂停的请求,从而向文件中写入图像。 def writeImage(self,fileneme): self._imageFilename=fileneme def startWritingVideo(self,filename,encoding=cv2.VideoWriter_fourcc('I','4','2','0')): self._videoFilename=filename self._videoEncoding=encoding def stopWritingVideo(self): self._videoFilename=None self._videoEncoding=None self._videoWriter=None def _writeVideoFrame(self): if not self.isWritingVideo: return if self._videoWriter is None: fps=self._capture.get(cv2.CAP_PROP_FPS) if fps==0.0: if self._framesElapsed<20: return else: fps=self._fpsEstimate size=(int(self._capture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(self._capture.get(cv2.CAP_PROP_FRAME_HEIGHT))) self._videoWriter=cv2.VideoWriter( self._videoFilename,self._videoEncoding,fps,size ) self._videoWriter.write(self._frame) writeImage(),startWritingVideo()和stopWritingVideo()是公有函数,简单地记录了文件的写入操作参数,实际写入会推迟到下一下exitFrame()函数。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册